面向对象的基本特征之一是“封装”,在C++类的定义中,我们需要通过访问控制修饰符private
,public
等对使用该类的“用户”能够访问到的数据进行限制。然而,C++由于历史原因(尤其是要兼容C语言)出现了友元的概念,我们可以定义能够自由访问private
数据的函数或类。当然,这破坏了面向对象的封装性,不过对于C++来说这种奇怪特性还是有其存在意义的。
友元函数可以突破标准OOP风格的访问控制访问类的私有属性,下面是一个例子。
#include <iostream>
class Demo {
private:
int i;
public:
Demo(int i) : i(i) {}
friend void test(Demo *d);
};
void test(Demo *d) { std::cout << d->i << std::endl; }
int main() {
Demo *d = new Demo(1);
test(d);
delete d;
return 0;
}
Demo1.i
是私有的成员变量,但是我们声明了友元函数后,这个函数就能自由使用Demo1
类中的所有数据了。
下面代码中,定义了Demo1的友元类Demo2,Demo2中就能自由使用Demo1类中的private
成员变量了。
#include <iostream>
class Demo1;
class Demo2;
class Demo1 {
private:
int i;
public:
Demo1(int i) : i(i) {}
void showI() { std::cout << this->i << std::endl; }
friend class Demo2;
};
class Demo2 {
public:
Demo1 *d;
Demo2(Demo1 *d) {
this->d = d;
this->d->i = 2;
}
};
int main() {
Demo1 *d1 = new Demo1(1);
Demo2 *d2 = new Demo2(d1);
d1->showI();
delete d1;
delete d2;
return 0;
}
友元类的的概念和友元函数相同,同样是使用friend
关键字进行定义。
友元的使用遵循以下几个特性: