C++之友元函数
类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。
友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。
如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字 friend
#include <iostream>
using namespace std;
class Friend {
private:
int width;
int length;
public:
Friend(int w) : width(w) {
cout << "created structure function" << endl;
cout << "width:" << width << endl;
};
Friend(const Friend &friends) {
cout << "copy structure function created" << endl;
//如果不将对象的成员变量width的值拷贝进来,则输出0
width = friends.width;
};
~Friend() {
cout << "deleted object" << endl;
}
friend void print_width(Friend friends);
void set_width(int w);
};
void Friend::set_width(int w) {
width = w;
}
void print_width(Friend friends) {
cout << "使用友元函数直接访问Friend类的私有成员变量:" << friends.width << endl;
}
int main() {
system("chcp 65001");
int width = 10;
Friend friends(width);
print_width(friends);
return 0;
}
输出:
Active code page: 65001
created structure function
width:10
copy structure function created
使用友元函数直接访问Friend类的私有成员变量:10
deleted object
deleted object
下面来看一下友元函数中普通参数对象的地址和实例化的地址是否相同
#include <iostream>
using namespace std;
class Father {
private:
int w;
int h;
public:
Father(int w, int h);
virtual ~Father();
friend void display(Father father, int a, int b);
int get_w();
int get_h();
};
Father::Father(int w, int h) : w(w), h(h) { cout << "Father constructed is created" << endl; }
Father::~Father() { cout << "Father destructed is used" << endl; }
int Father::get_w() { return this->w; }
int Father::get_h() { return this->h; }
void display(Father father, int a, int b) {
father.w = a;
father.h = b;
cout << "father地址:" << &father << endl;
cout << "w:" << father.w << endl
<< "h:" << father.h << endl;
}
int main() {
Father father(1, 2);
display(father, 3, 4);
int h = father.get_h();
int w = father.get_w();
cout << "地址:" << &father << endl;
cout << "h:" << h << endl
<< "w:" << w << endl;
return 0;
}
输出:
Father constructed is created
father地址:0x7ffeea49e7b8
w:3
h:4
Father destructed is used
地址:0x7ffeea49e7c8
h:2
w:1
Father destructed is used
通过上述程序发现,虽然传入友元函数display中的对象是Father实例化的对象,但是地址却和Father实例化对象的地址不同。这说明我们将father对象传入后,系统为其开辟了一个新的内存空间,所以对其操作就不会影响到实参中成员变量的值了。
友元函数是非成员函数,如果想要改变类中私有成员变量的值,则需要传参的时候传入引用对象或者指针对象。
#include <iostream>
using namespace std;
class InLineClass {
public:
InLineClass(int x, int y) : a(x), b(y) {
this->a = x;
this->b = y;
printf("create structure function\n");
}
InLineClass(const InLineClass &in) {
this->a = in.a;
this->b = in.b;
printf("copy structure function is created");
}
~InLineClass() {
printf("destructed function deleted object");
}
int max() {
return this->a < this->b ? b : a;
}
friend void friends_function(InLineClass &inLineClass, int i, int j);
//传入指针的写法
/**friend void friends_function(InLineClass *inLineClass, int i, int j);**/
private:
int a;
int b;
};
void friends_function(InLineClass &inLineClass, int i, int j) {
inLineClass.a = i;
inLineClass.b = j;
}
//传入指针的写法,和结构体类似,符号为->
/**void friends_function(InLineClass *inLineClass, int i, int j) {
inLineClass->a = i;
inLineClass->b = j;
}**/
int main() {
system("chcp 65001");
int x = 2;
int y = 3;
int x_change = 10;
int y_change = 20;
InLineClass inlineclass(x, y);
//传入指针写法
//friends_function(&inlineclass, y_change, x_change);
friends_function(inlineclass, y_change, x_change);
auto max_value = inlineclass.max();
cout << "函数最大值:" << max_value << endl;
return 0;
}
输出:
Active code page: 65001
create structure function
函数最大值:20
destructed function deleted object