前置声明和友元成员函数

什么是友元成员函数?很多时候没有必要把一个类声明为另一个类的友元类,因为后一个类已经提供了很多public接口,前一个类可以直接用,只是在前一个类的某些成员函数中需要调用后一个类的private成员,那么这个时候只需要把那些成员函数声明为后一个类的友元函数即可。就像下面这样:



这个set_chan属于Remote类,但是现在要把它声明为TV类的友元函数。
不过,这会引起一个问题。编译器必须要知道Remote是个类,而且这个set_chan是Remote类的一个成员函数,所以它必须要先看到Remote的声明式,这决定了Remote类的声明式必须出现在TV类的上面。
但是,因为这个set_chan是TV类的友元函数,那么Remote也必须先知道这个TV是个类才行。
那么为了满足这两者的要求,C++推出了类的前置声明式,如下图所示:



它的用法如下所示:

现在这个问题得以解决,所以由此可以得知,类的前置声明式的作用就是告诉下面某个标签是个类而已。
但是现在又出现了一个问题,那就是在Remote中有一个内联函数onoff,它调用了TV的对象进行代码的实现。因为onoff的代码写在Remote声明式中,编译器必须要在onoff调用TV对象的时候知道TV对象有onoff所要调用的东西。可实际上TV类的声明式在Remote类的下面,Remote类的上面只是个TV类的前置声明而已,Remote类的内部无法知道TV类具体长成什么样子,因此onoff要调用TV类对象的东西时表示茫然无知。
所以为了使TV对象的内部细节在onoff来看是赤裸裸的,就必须让TV类的声明式在onoff之上才行,也就是说让onoff的定义放在TV类的声明式之下。即下图所示:




在这里C++ Primer Plus的解决办法是在Remote类中只保留函数声明,把函数定义统统放在下面,如果是内联函数,你直接在函数定义上加上inline关键字即可。这是一种快刀斩乱麻的解决办法。
不同于其他成员函数,inline函数可以把定义放在头文件中,如下图所示:

测试代码及运行结果如下所示:

而其他函数就不能定义在头文件中了,如下图所示:


现在我把inline函数定义在cpp中。


从上图可知,inline函数只能定义在头文件中。
Inline函数具有内部连接属性,也就是说它只能存在于它被调用的地方,而且还必须是头文件,所以上面的onoff只能放在头文件中。
还需要注意的是,声明友元类时没必要使用类的前置声明式,虽然你可以选择这么做,那是因为友元类的声明式



足以说明它自己是个类。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,049评论 25 709
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,354评论 9 118
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,314评论 19 139
  • 蒋勋说文学之美 5.26周五,共读本书的第1页至第21页。 1 蒋勋先生说,诗很像一粒珍珠,它是要经过琢磨的。我们...
    Jean_zz阅读 3,950评论 0 0
  • 昨天下班,和张先生一起回家吃饭。因为前天看完了《微微一笑很倾城》,所以暂时没有别的剧要追,于是有些无所事事,整个人...
    Ms_Y_杨小姐阅读 1,131评论 0 0