生活中你的家有客厅(Public),有你的卧室(Private)
客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去
但是呢,你也可以允许你的好闺蜜好基友进去。
在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术
友元的目的就是让一个函数或者类 访问另一个类中私有成员
友元的关键字为 friend
友元的三种实现
- 全局函数做友元
- 类做友元
- 成员函数做友元
全局函数做友元
全局函数做友元写法,正常写,只需要在我们需要调用的对象的类里面加上“ friend 函数声明 ; ”即可在外部用函数调用类里面的私有属性。
class Building { //告诉编译器 goodGay全局函数 是 Building类的好朋友,可以访问类中的私有内容 friend void goodGay(Building * building); public: Building() { this->m_SittingRoom = "客厅"; this->m_BedRoom = "卧室"; } public: string m_SittingRoom; //客厅 private: string m_BedRoom; //卧室 }; //这里传指针或者传引用都可以 void goodGay(Building * building) { cout << "好基友正在访问: " << building->m_SittingRoom << endl; cout << "好基友正在访问: " << building->m_BedRoom << endl; } void test01() { Building b; goodGay(&b); } int main(){ test01(); system("pause"); return 0; }
友元类
//类的声明(告诉编译器有这个类在后面,类比于函数声明) class Building; class goodGay { public: goodGay(); void visit(); //参观函数 用来访问Building中的属性 private: Building *building; }; class Building { //告诉编译器 goodGay类是Building类的好朋友,可以访问到Building类中私有内容 friend class goodGay; public: Building(); public: string m_SittingRoom; //客厅 private: string m_BedRoom; //卧室 }; //类外写成员函数 Building::Building() { this->m_SittingRoom = "客厅"; this->m_BedRoom = "卧室"; } goodGay::goodGay() { //创建建筑物对象,内部指针指向new出来的对象 building = new Building; } void goodGay::visit() { cout << "好基友正在访问" << building->m_SittingRoom << endl; cout << "好基友正在访问" << building->m_BedRoom << endl; } void test01() { goodGay gg; gg.visit(); } int main(){ test01(); system("pause"); return 0; }
我们来看一下上述代码的流程:
先创建一个GoodGay对象gg,创建之后先调用GoodGay构造函数, 创建一个Building,调用Building构造函数,并对Building内部属性赋初值。下面再调用visit函数,就可以访问Building内部的客厅/卧室了。
成员函数做友元
class Building; class goodGay { public: goodGay(); void visit(); //只让visit函数作为Building的好朋友,可以发访问Building中私有内容 void visit2(); private: Building *building; }; class Building { //告诉编译器 goodGay类中的visit成员函数 是Building好朋友,可以访问私有内容 friend void goodGay::visit(); public: Building(); public: string m_SittingRoom; //客厅 private: string m_BedRoom;//卧室 }; Building::Building() { this->m_SittingRoom = "客厅"; this->m_BedRoom = "卧室"; } goodGay::goodGay() { building = new Building; } void goodGay::visit() { cout << "好基友正在访问" << building->m_SittingRoom << endl; cout << "好基友正在访问" << building->m_BedRoom << endl; } void goodGay::visit2() { cout << "好基友正在访问" << building->m_SittingRoom << endl; //cout << "好基友正在访问" << building->m_BedRoom << endl; } void test01() { goodGay gg; gg.visit(); } int main(){ test01(); system("pause"); return 0; }
流程:
调用test01函数,创建一个对象,对象会访问visit函数。
在创建一个对象的时候,会调用它的构造函数,构造函数中创建了一个Building,Building也会把一个属性做赋初值的操作。后面就直接调用visit函数调用访问属性。
注意:
//告诉编译器 goodGay类中的visit成员函数 是Building好朋友,可以访问私有内容
friend void goodGay::visit();