C++之友元的使用方法
C++中友元的实例详解
尽管友元被授予从外部访问类的私有部分的权限,但他们并不与面向对象的编程思想相悖;相反他提高了公共接口的灵活性。
一、友元类
友元声明可以位于公有、私有活保护部分、其所在位置无关紧要
我直接贴出一个摘自< c++ primer plus >的例子来演示 c++ 友元类
其中 Remote 为 Tv的友元类。
Tv.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
|
Tv.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
|
测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
上述代码中将Remote类设置成为了Tv类的友元类,但事实上我们看到:唯一访问Tv的成员的方法是void set_chan(Tv &t, int c) { t.channel = c; } ,因此它是唯一需要友元的方法。因此不必让整个类成为友元,这就引出了我们下面要讲的的友元成员函数。
二、友元成员函数
我们要再Tv中将Remote::set_chan()设置成友元:
1 2 3 4 |
|
然而要使编译器能够处理这条语句,它必须知道Remote的定义。否则,它无法知道Remote是一个类。而 set_chan是这个类的方法。这意味着应将Remote的定义放到Tv的定义前面。Remote的方法提到了Tv对象,而意味着Tv定义应当位于Remote定义之前,避开这种循环依赖的方法是,使用前向声明。
所以应该这样:
1 2 3 |
|
这里还有一个麻烦就是:
Remote 包含了内联代码例如:void onoff(Tv &t) {t.onoff();};
由于这将调用Tv的一个方法,所以编译器此时已经看到了Tv类的声明,这样才能知道Tv有哪些方法,但正如看到的,该声明位于Remote声明的后面。这种问题的解决方法是:使用Remote声明中只包含方法声明,并将实际的定义放到Tv类之后。 所以最终应该这样:
1 2 3 4 |
|
这里通过方法定义中使用 inline关键字,仍然可以使方法称为内联方法
所以程序最终将tv.h改为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
|
测试结果不变。
*另外:也可一个将内联函数放在tv.cpp中,但必须去掉inline关键字,这样函数的连接性将成为外部的。
三、其他友元关系
1、上面的代码表示的是Remote是Tv的友元。但我们有时也会用到2个类互相友元。即Remote是Tv的友元,同时 Tv又是Remote的友元
他们定义与下面类似:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
由于Remote的声明位于Tv声明的后面,所以可以在类的定义Remote::volup(),但Tv::buzz()方法必须在Tv声明的外部定义,使其位于Remote声明的外面。如果不希望buzz()是内联的,则应在一个单独的方法定义文件中定义它。
2、共同的友元。
需要使用友元的另一种情况是,函数需要访问两个类的私有数据。它可以是一个类的友元,同时是另一个类的友元。示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
相信小伙伴们看完这篇C++之友元的使用方法详细内容后,对C++的知识点更进一步了,我们每天都会上新一些技术含量高的文章给大家阅读,想要学习就不能错过。
上一篇:C++之汉诺塔实例代码
下一篇:C++中如何调用C函数