为了可以在类外部某些特定的作用域内访问类内的私有属性。
对于class来说,它里面默认有三个区域。
下面我们通过一张图来更加直观的了解一下。
可以看到,我们在类外通过对象直接访问类内的私有属性Bedroom,会报错。而访问公共权限下的 Liviing_room却不会出错。这就是因为test1不是这个building类的友元。
二:全局函数做友元如果我们将这个test1定义为building的友元函数,那么在这个test1函数内部,就可以直接访问building类的私有权限中的属性。(有路径就行)。话不多说,我们直接上正题。
其实相对来说,我们在创建一个类的时候,通常都会将它的成员属性进行私有化的,那如果我非要使用,test1函数直接访问到building类的私有属性,那该咋办呢?
其实非常简单,我们只需要加上两句代码就可以使得在test1函数内部访问building类的私有属性了。
注意事项:可以看到,在添加了这两条代码之后,编译器刚才报出的警告没有了。现在只要有路径,就可以直接访问building类内部私有属性,并且可以修改私有属性的数据。
三:整个类做友元因为这里的代码都是从上到下顺序执行的,那么我们尽量要在类上面加上友元函数test1的声明,虽然不加编译器也能跑得过。但是该加还是得加。
(1)先对两个类进行声明 (2)将要被声明为友元类的类定义在另一个类上方这里就要注意了:因为在程序运行起来时,一直都是顺序执行的,所以在这里要严格按照顺序去实现。(我刚开始没有按照顺序去实现,所以编译器会老是报错,没有这个类,没有那个类的。)
(3)两个类构造函数的实现顺序这里为了方便观察,所以我将两个类分开截图了,但是通过行号依然可以看出,先定义的breather类,后定义的building类。
这里要注意:在实现这两个类的定义时,对于类中的成员函数与构造函数,我们都只进行简单声明 ,不要在这里实现他们,因为代码顺序执行的原因,会报错!!!
(4)最后一步(实在不知道取什么名了.....)我们一定要按照顺序去先实现,building类的构造函数,后实现breather类的构造函数,因为在一个类(主类)中包含其他类(从类)时,创建一个主类对象,编译器是会优先生成从类的。
在building类中声明一下breather类是它的友元类,并将breather类中的vist函数实现,可以看到它现在确实可以直接访问building类的私有属性了
我们直接让代码走起来,可以看到结果很明确。通过breather中的vist函数,可以直接访问building类的私有属性了。
四:类中成员函数作友元在了解了上面两种友元的定义方式,这个实现起来就比较简单了,直接将类的友元的声明代码修改一下进行了。
现在在breather类中,只有在vist函数体内才能访问building类的私有属性了。
最后附上完整代码
#include#include using namespace std; class building; class breather; void test1(); class breather { public: breather(); void vist(); void vist1(); building* buil; }; class building { friend void test1(); //friend class breather; friend void breather::vist(); public: building(); string living_room;//客厅 private: string Bedroom;//卧室 }; building::building()//先实现building的构造函数 { this->Bedroom = "私人卧室"; this->living_room = "公共客厅"; } breather::breather()//实现breather类的构造函数 { this->buil = new building; } void breather::vist() { cout << this->buil->living_room << endl; cout << this->buil->Bedroom<< endl; } void breather::vist1() { cout << this->buil->living_room << endl; //cout << this->buil->Bedroom << endl; //为了对比vist函数 } void test2() { breather b1; b1.vist(); } void test1() { building b1; cout << b1.Bedroom << endl; cout << b1.living_room << endl; b1.living_room = "客厅"; b1.Bedroom = "卧室"; } int main() { test2(); return 0; }



