目录
友元
友元的关键字 friend
友元的三种实现方式
1. 全局函数做友元
2. 类做友元
3. 成员函数做友元
友元
生活中你的家有客厅(Public),有你的卧室(Private)
客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去
但是呢,你也可以允许你的好闺蜜好基友进去。
在程序中,有些私有属性 也想让一些特殊的类或者类外特殊的函数访问,需要友元。
友元的目的是让一个函数或者类访问另一个类中的私有成员
类的主要特点是封装性,即类的私有成员只能被它自己的成员函数访问,类外的函数无法访问类的私有成员。有时候,外部函数需要直接访问类的私有数据成员,以便提高效率,这时就可以把这个外部函数定义为该类的友元函数。这种在某个类定义中用friend声明一个外部函数(也许是其他类的成员函数)的方法,就好像宣布了一种“亲友”关系,这个外部虽然不是该类的成员函数,却可以访问该类的所有成员,无论是公有成员还是私有成员。
如果没有友元机制,则只能将类的所有成员都定义为公有的,任何函数都可以无约束地访问它,但是这样做就破坏了类的封装性。而友元机制可以在不破坏类的封装性的前提下,提高类成员访问的灵活性。
友元函数常常是一个类的一个成员函数,这样通过友元函数可以使一个类对象直接访问另一个类对象的私有成员。这种成员函数不仅可以访问自己所在本类对象中的私有成员,还可以访问friend声明所在类的对象中的私有与公有成员。
当友元函数是另一个类的成员函数时,还应该在另一个类中声明它的友元关系。声明语句的格式为:
friend<函数类型><类名>::<函数名>(<形参表>);
说明:
(1)友元函数虽然可以访问对象的私有成员,但它毕竟不是类的成员函数,因此,在类的外部定义友元函数时,不必像成员函数那样在函数名之前加上“类名::”。
(2)友元函数一般带有一个该类的入口参数。因为友元函数不是类的成员,所以它不能直接引用对象成员的名字,也不能通过this指针引用对象成员。它必须通过作为入口参数传递过来的对象名或对象指针来引用该对象的成员。
友元的关键字 friend
友元的三种实现方式
-
全局函数做友元
-
类做友元
-
成员函数做友元
1. 全局函数做友元
示例:
#include<iostream>#include<string>using namespace std;// 房屋的类class building{// 设置 good 函数为友元 可以访问私有属性friend void good(building &Building);public:building(){m_sittingroom = "客厅";m_bedroom = "卧室";}string m_sittingroom;private:string m_bedroom;};// 全局函数void good(building &Building){cout<<"全局函数访问:"<<Building.m_sittingroom<<endl;cout<<"全局函数访问:"<<Building.m_bedroom<<endl;}int main(){building Building;good(Building);return 0;}
运行结果:
2. 类做友元
示例:
#include<iostream>#include<string>using namespace std;class building;class good_g{public:good_g();void visit(); // 参观访问Building中的属性private:building *Building;};// 房屋的类class building{// 设置good_g为本类的友元friend class good_g;public:building();string m_sittingroom;private:string m_bedroom;};// 类外写成员函数building::building(){this->m_sittingroom = "客厅";this->m_bedroom = "卧室";}good_g::good_g(){// 创建一个建筑物对象Building = new building; // 在堆区创建一个对象}void good_g::visit(){cout<<"good_g类正在访问:"<<Building->m_sittingroom<<endl;cout<<"good_g类正在访问:"<<Building->m_bedroom<<endl;}void test01(){good_g gg;gg.visit();}int main(){test01();return 0;}
运行结果:
3. 成员函数做友元
示例:
#include<iostream>#include<string>using namespace std;class building;class good_g {public:good_g();void visit(); // 参观访问Building中的属性void visit2(); // 访问不到building中的私有成员private:building* Building;};// 房屋的类class building {// good_g 类下的函数作为本类的友元,要加作用域才可以访问私有内容friend void good_g::visit();public:building();public:string m_sittingroom;private:string m_bedroom;};// 类外写成员函数building::building(){this->m_sittingroom = "客厅";this->m_bedroom = "卧室";}good_g::good_g(){// 创建一个建筑物对象Building = new building; // 在堆区创建一个对象}void good_g::visit(){cout << "visit 正在访问:" << Building->m_sittingroom << endl;cout << "visit 正在访问:" << Building->m_bedroom << endl;}void good_g::visit2(){cout << "visit2 正在访问:" << Building->m_sittingroom << endl;//cout<<"visit2 正在访问:"<<Building->m_bedroom<<endl;// visi2 访问不到buiding类中的私有成员,没有设置友元}void test01(){good_g gg;gg.visit();gg.visit2();}int main(){test01();return 0;}
运行结果: