生活中你的家有客厅(Public),有你的卧室(Private)
客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去
但是,你也可以允许你的好朋友进去。
在程序里,有些私有属性也想让类外特殊的一些函数或者类进行访问,就需要用到友元技术
友元的目的就是让一个函数或者类访问另一个类中的私有成员
友元的关键字为 friend
友元的三种实现
1、全局函数做友元
2、类做友元
3、成员函数做友元
一、全局函数做友元
示例:没有加friend是访问不到类内private类的
//建筑物类
class Building
{
public:
Building() //构造函数
{
m_BedRoom = "客厅";
m_SittingRoom = "卧室";
}
public:
string m_SittingRoom; // 客厅
private:
string m_BedRoom; //卧室
};
//全局函数: 该全局函数能访问公有成员,但不能访问私有成员
void goodGay(Building* building) //引用和指针都可以传递,这里用指针传递
{
cout << "好基友全局函数 正在访问:" << building->m_SittingRoom << endl;
//下面这行报错,因为不能访问私有成员
cout << "好基友全局函数 正在访问:" << building->m_BedRoom << endl;
}
示例:加入friend后可以访问类内私有成员
#include<iostream>
#include<string>
using namespace std;
//建筑物类
class Building
{
//goodGay全局函数是Building的好朋友,可以访问Building中私有的成员
friend void goodGay(Building* building); //声明
public:
Building() //构造函数
{
m_BedRoom = "客厅";
m_SittingRoom = "卧室";
}
public:
string m_SittingRoom; // 客厅
private:
string m_BedRoom; //卧室
};
//全局函数: 该全局函数能访问公有成员,但不能访问私有成员
void goodGay(Building* building) //引用和指针都可以传递,这里用指针传递
{
cout << "好基友全局函数 正在访问:" << building->m_SittingRoom << endl;
//因为void goodGay(Building* building)在声明中是friend类,所以有类内私有的访问权限
cout << "好基友全局函数 正在访问:" << building->m_BedRoom << endl;
}
void test01()
{
Building building; //创建对象,创建的同时完成了构造函数赋初值的操作
goodGay(&building);
}
int main()
{
test01();
return 0;
}
运行结果:加入friend后可以访问类内私有成员
二、类做友元
类做友元就是让一个类能访问另一个类的私有成员
示例: 一个类能访问另一个类的私有成员
#include<iostream>
#include<string>
using namespace std;
//类做友元
class Building; //先声明有这个类
class GoodGay
{
public:
GoodGay(); //构造函数,在类外写
void visit(); //参观函数 访问Building中的属性
Building* building; //有building的一个指针
};
class Building
{
//GoodGay类是本类的好朋友,可以访问本类中私有成员
friend class GoodGay;
public:
Building(); //构造函数,在类外写
public:
string m_SittingRoom;
private:
string m_BedRoom;
};
//类外写成员函数
Building::Building() //Building作用域下的Building函数
{
m_SittingRoom = "客厅";
m_BedRoom = "卧室";
}
GoodGay::GoodGay() //GoodGay作用域下的构造函数
{
//创建建筑物对象
building = new Building; //在堆区创建了一个对象,building指向这个对象
}
void GoodGay::visit() //GoodGay作用域下的一个visit函数
{
cout << "好基友类正在访问:" << building->m_SittingRoom << endl;
//若没有加friend是访问不了m_BedRoom,此时在Building类中加入了GoodGay的friend声明,所以可以访问
cout << "好基友类正在访问:" << building->m_BedRoom << endl;
}
void test01()
{
GoodGay gg; //创建一个对象,先调用构造函数
gg.visit();
}
int main()
{
test01();
return 0;
}
运行结果:GoodGay类能访问Building类中的私有成员
三、成员函数做友元
示例:成员函数做友元
#include<iostream>
#include<string>
using namespace std;
class Building; //先声明有Building类
class GoodGay
{
public:
GoodGay();
void visit(); //让visit函数可以访问Building中的私有成员
void visit2(); //让visit2访问不到Building中的私有成员
Building* building;
};
class Building
{
//告诉编译器GoodGay类下的visit成员函数作为本类的好朋友, 可以访问私有成员
friend void GoodGay::visit(); //GoodGay作用域下的友元成员函数
public:
Building(); //构造函数的声明,用来初始化属性,实现都在类外实现
public:
string m_SittingRoom; //客厅
private:
string m_BedRoom; //卧室
};
//类外实现成员函数
Building::Building() //Building作用域下的Building构造函数
{
m_SittingRoom = "客厅"; //赋初值
m_BedRoom = "卧室";
}
GoodGay::GoodGay() //GoodGay作用域下的构造函数
{
building = new Building;//创建Building对象在堆区并且通过building来维护这个对象
}
void GoodGay::visit() //GoodGay作用域下的visit
{
cout << "visit函数正在访问:" << building->m_SittingRoom << endl; //访问客厅
//因为在Building类中,告诉编译器GoodGay类下的visit成员函数作为本类的好朋友, 可以访问私有成员
cout << "visit函数正在访问:" << building->m_BedRoom << endl; //访问卧室
}
void GoodGay::visit2() //GoodGay作用域下的visit2
{
cout << "visit2函数正在访问:" << building->m_SittingRoom << endl; //访问客厅
//因为在Building类中,visit2成员函数不是本类的好朋友, 所以不可以访问私有成员
//cout << "visit2函数正在访问:" << building->m_BedRoom << endl; //访问卧室
}
void test01()
{
GoodGay gg;
gg.visit();
gg.visit2();
}
int main()
{
test01();
return 0;
}
运行结果:visit( )作为友元成员函数可以访问公有和私有成员属性,visit2( )只能访问共有成员属性