在C++中,私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口(成员函数)间接地进行。这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的麻烦。
比如:你自己的卧室,除了你的家人可以(参观)访问外,你可以让一些信任的好友进入你的卧室,对他们公开一些自己的隐私。
一、友元函数
在定义一个类的时候,可以把一些函数(包括全局函数和其他类的成员函数)声明为“友元”,这样那些函数就成为该类的友元函数,在友元函数内部就可以访问该类对象的私有成员了。
将全局函数声明为友元的写法如下:
friend 返回值类型 函数名(参数表);
类的成员函数声明为友元的写法如下:(不能把其他类的私有成员函数声明为友元。)
friend 返回值类型 其他类的类名::成员函数名(参数表);
#include<iostream>
using namespace std;
class CCar; //提前声明CCar类,CDriver类使用到CCar类的指针
class CDriver
{
public:
void ModifyCar(CCar* pCar); //改装汽车
};
class CCar
{
private:
int price;
friend int MostExpensiveCar(CCar cars[], int total); //声明友元
friend void CDriver::ModifyCar(CCar* pCar); //声明友元
};
void CDriver::ModifyCar(CCar* pCar)
{
pCar->price += 1000; //汽车改装后价值增加
}
int MostExpensiveCar(CCar cars[], int total) //求最贵气车的价格
{
int tmpMax = -1;
for (int i = 0; i<total; ++i)
if (cars[i].price > tmpMax) // cars[i] 的私有成员 price
tmpMax = cars[i].price;
return tmpMax;
}
int main()
{
return 0;
{
将全局函数 MostExpensiveCar 声明为 CCar 类的友元,因此可以用cars[i].price可以访问 cars[i] 的私有成员 price。
CDriver 类的 ModifyCar 成员函数声明为友元,因此可以用 pCar->price可以访问 pCar 指针所指向的对象的私有成员变量 price。
二、友元类
一个类 A 可以将另一个类 B 声明为自己的友元,类 B 的所有成员函数就都可以访问类 A 对象的私有成员。(A声明B是自己的好友,那么B 可以访问自己(A)的卧室。我是这样理解的)
在类定义中声明友元类的写法如下:
friend class 类名;
class CCar
{
private:
int price;
friend class CDriver; //声明 CDriver 为友元类(同时也是声明 CDriver 是一个类)
};
class CDriver
{
public:
CCar myCar;
void ModifyCar() //改装汽车
{
myCar.price += 1000; //因CDriver是CCar的友元类,故此处可以访问其私有成员
}
};
int main()
{
return 0;
}
注意:
友元关系没有继承性
假如类B是类A的友元,类C继承于类A,那么友元类B是没办法直接访问类C的私有或保护成员。
友元关系没有传递性
友元关系在类之间不能传递,即类 A 是类 B 的友元,类 B 是类 C 的友元,并不能导出类 A 是类 C 的友元。“咱俩是朋友,所以你的朋友就是我的朋友”这句话在 C++ 的友元关系上不成立。
关于友元类详情,可以查看:https://www.cnblogs.com/yongdaimi/p/9558498.html