伴随着C++的学习历程,我们会发现C++就像一个雷区,在雷区里面行走需要注意雷的分布和战斗力,今天我们来认识的是C++中比较不受重视的一个雷,叫做友元,战斗力十分生猛,友元的存在一定程度上破坏了C++的结构稳定性即封装性,但是一定程度上又方便了开发者的使用,是一把双刃剑,因此开发人员在使用时候一定要注意,friend赋予类或者函数对本类中的所有数据进行访问,即private、protected和public数据都可以被友元类或者友元函数所访问,正如友元的名字一样,对朋友你不仅不告诉他你的平常事情,什么烦心事情呀,较为隐私的呀都可以跟朋友聊,正如友元可以访问本类的所有数据一样,一个道理。
下面我们就来讲一下友元的分类:
**
1、友元函数
**
1)其他类的函数作为本类的友元函数;
class A{
public:
A();
...
friend void B::show(A& a);
private:
int x;
int y;
};
class B{
public:
B();
...
void show(A& a);
private:
int xx;
int yy;
};
void B::show(A& a){
std::cout<<a.x<<" "<<a.y<<std::endl;
std::cout<<"我可以访问a的所有数据啦,真开心!"<<std::endl;
}
2)普通函数作为本类的友元函数;
class A{
public:
A();
...
friend void show(A*a){
cout<<a->x<<endl;
}
private:
int x;
int y;
};
**
2、友元类
**
class A{
public:
A();
...
friend B b;
private:
int x;
int y;
};
class B{
public:
B();
...
void show(A& a);
private:
int xx;
int yy;
};
void B::show(A& a){
std::cout<<a.x<<" "<<a.y<<std::endl;
std::cout<<"哈哈哈,我可以访问A的数据啦,因为我是A的友元类"<<std::endl;
}
PS:值的注意的是,我们不仅应该理解friend友元类型,更应该从深层次加以考虑,理解它的特性显得相当重要,列举如下:
1)友元不具有对称性;A是B的友元,意味这A可以访问B的所有数据,并不意味这B可以反过来访问A的所有数据;
2)友元不具有传递性;B是A的友元,C是B的友元,则不能认为C是A的友元,没有任何关系,除非声明C是A的友元;
3)友元不能被继承。B是A的友元,C是B的子类,不能认为C是A的友元,正如乾隆(B)是和珅(A)的友元,嘉庆(C)是乾隆的儿子,也就是C继承了B,然而嘉庆并不是和珅的友元,即C并不是A的友元,因此我们可以按上面的这种奇怪的思路加以理解,友元关系是不能被继承的。