为了可以在类外部某些特定的作用域内访问类内的私有属性。
对于class来说,它里面默认有三个区域。
下面我们通过一张图来更加直观的了解一下。
可以看到,我们在类外通过对象直接访问类内的私有属性Bedroom,会报错。而访问公共权限下的 Liviing_room却不会出错。这就是因为test1不是这个building类的友元。
如果我们将这个test1定义为building的友元函数,那么在这个test1函数内部,就可以直接访问building类的私有权限中的属性。(有路径就行)。话不多说,我们直接上正题。
其实相对来说,我们在创建一个类的时候,通常都会将它的成员属性进行私有化的,那如果我非要使用,test1函数直接访问到building类的私有属性,那该咋办呢?
其实非常简单,我们只需要加上两句代码就可以使得在test1函数内部访问building类的私有属性了。
可以看到,在添加了这两条代码之后,编译器刚才报出的警告没有了。现在只要有路径,就可以直接访问building函数内部,并且可以修改私有属性的数据。
因为这里的代码都是从上到下顺序执行的,那么我们尽量要在类上面加上友元函数test1的声明,虽然不加编译器也能跑得过。但是该加还是得加。
这里就要注意了:因为在程序运行起来时,一直都是顺序执行的,所以在这里要严格按照顺序去实现。(我刚开始没有按照顺序去实现,所以编译器会老是报错,没有这个类,没有那个类的。)
这里为了方便观察,所以我将两个类分开截图了,但是通过行号依然可以看出,先定义的breather类,后定义的building类。
这里要注意:在实现这两个类的定义时,对于类中的成员函数与构造函数,我们都只进行简单声明 ,不要在这里实现他们,因为代码顺序执行的原因,会报错!!!
我们一定要按照顺序去先实现,building类的构造函数,后实现breather类的构造函数,因为在一个类(主类)中包含其他类(从类)时,创建一个主类对象,编译器是会优先生成从类的。
在building类中声明一下breather类是它的友元类,并将breather类中的vist函数实现,可以看到它现在确实可以直接访问,building类的私有属性了
我们直接让代码走起来,可以看到结果很明确。通过breather中的vist函数,可以直接访问building类的私有属性了。
在了解了上面两种友元的定义方式,这个实现起来就比较简单了,直接将类的友元的声明代码修改一下进行了。
现在在breather类中,只有在vist函数体内才能访问building类的私有属性了。
最后附上完整代码
- #include<iostream>
- #include<string>
- 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;
- }