同类对象间无私处,异类对象间有友元
类的主要特点之一是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问。但是,有时候需要在类的外部访问类的私有成员,怎么办?
解决方法是使用友元函数,友元函数是一种特权函数,c++允许友元访问私有成员。
可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元。
目录
一、友元几点说明
[友元类注意]
|
友元声明以关键字friend开始,它只能出现在类定义中。因为友元不是授权类的成员,所以它不受其所在类的声明区域public
private和protected的影响。通常我们选择把所有友元声明组织在一起并放在类头之后.
二、全局函数做友元
全局函数做友元固定格式:
在类的开头,无需写权限。关键字friend + 声明要做友元的函数,在类外实现。
例子:
class Building
{
//让全局函数 goodGay作为本类Building中的好朋友,可以访问私有成员
friend void goodGay(Building & building);
public:
Building()
{
m_SittingRoom = "客厅";
m_BedRoom = "卧室";
}
public:
//客厅
string m_SittingRoom;
private:
//卧室
string m_BedRoom;
};
//好基友 全局函数 可以访问客厅 也可以访问卧室
void goodGay(Building & building)
{
cout << "好基友正在访问: " << building.m_SittingRoom << endl;
cout << "好基友正在访问: " << building.m_BedRoom << endl;
}
int main(){
Building building;
goodGay(building);
system("pause");
return EXIT_SUCCESS;
}
三、类做友元
全局函数做友元固定格式:
在类的开头,无需写权限。关键字friend + 声明要做友元的类。
例子:(让GoodGay类作为 Building类的好朋友,可以访问Building类中私有成员)
class GoodGay
{
public:
GoodGay()
{
building = new Building;
}
void visit()
{
cout << "好基友类正在访问: " << building->m_SittingRoom << endl;
cout << "好基友类正在访问: " << building->m_BedRoom << endl;
}
Building * building;
};
class Building
{
//让GoodGay类作为 Building类的好朋友,可以访问Building类中私有成员
friend class GoodGay;
public:
Building()
{
m_SittingRoom = "客厅";
m_BedRoom = "卧室";
}
string m_SittingRoom;
private:
string m_BedRoom;
};
int main(){
GoodGay gg;
gg.visit();
system("pause");
return EXIT_SUCCESS;
}
四、类中的成员做友元
全局函数做友元固定格式:
在类的开头,无需写权限。关键字friend + 声明要做友元类中的成员。
class GoodGay
{
public:
GoodGay()
{
building = new Building;
}
//只有visit这个成员函数 ,可以访问Building中的私有成员,其他函数不可以
void visit()
{
cout << "好基友的visit函数正在访问: " << building->m_SittingRoom << endl;
cout << "好基友的visit函数正在访问: " << building->m_BedRoom << endl;
}
Building * building;
};
class Building
{
//告诉编译器 GoodGay类中的visit函数 是本类的好朋友,可以访问本类中私有成员
friend void GoodGay::visit();
public:
Building()
{
m_SittingRoom = "客厅";
m_BedRoom = "卧室";
}
string m_SittingRoom; //客厅
private:
string m_BedRoom; //卧室
};
int main(){
GoodGay gg;
gg.visit();
system("pause");
return EXIT_SUCCESS;
}