想了好久还是用这种方式水一水了。其实C++ Primer Plus并不适合有编程基础之后去读,不过懒得再找书了。学C++的过程中很尴尬的一点是实践机会不多,这样也能尽可能避免过目就忘的情况,权当笔记,会摘抄书中的一些代码。
先从第15章开始。
使用友元类适合这样的关系:友元类需要访问原始类的私有部分,两个类是亲密的伙伴关系而不是“服务器-客户端”的关系,使用友元类需要原始类的同意(即原始类声明中的friend
),意味着友元类和原始类同时产生。典型的例子就是书中的电视和遥控器的关系。
在原始类的声明中指定友元类,使用friend class 类名
来实现。
友元类的特点
[ssbluelist]
相比于上面将整个类都作为友元,友元成员函数“只信任类的一部分”,使用作用域解析来指定类中的某个方法。
class Tv { friend void Remote::set_chan(Tv & t, int c); }
作用域解析运算符::
左边是一个类,但是要让编译器知道这是一个类而不是别的什么(比如命名空间),需要将含有友元成员函数的类声明放到原始类声明前面,但这个成员函数在声明中又不可避免地使用到原始类,又需要把它放到后面。
解决方法是向前声明,将友元成员函数所在的类声明放在前面,在它的前面再加一句class 原始类
指出::
左边是一个类。
这样的话,友元成员函数就不要使用内联代码,因为如果把实现写在了声明里,当编译器走到实现的时候并不知道原始类有什么方法。应当把友元成员函数的定义放到原始类声明之后。(总结一句话:友元成员函数不能内联,类中只包含友元成员函数的声明)
仍然要将友元成员函数作为内联方法,在方法定义前加inline
。
假设原始类要访问友元类的私有/保护成员,那么需要让原始类成为友元类的友元,也就是互为friend
。
与前面类似,定义统统放到声明后面。
一个函数可以是两个类的友元,同样,这两个类在声明的时候一定会出现一个先于另一个提到后者,那么也要使用向前声明。
总之,一定要让编译器获得足够的信息,在提到一个类之前必须表明它是个类。使用向前声明,让尚未正式声明的类提前强调自己的身份。
在类中声明友元类时使用friend class 友元类
,class
表明跟在它后面的是一个类,所以不需要向前声明。
包含和嵌套类很容易区分,前者是在类中使用别的类对象(对象是成员),后者是在类中定义类(嵌套类是成员)。
在外部使用嵌套类,用到作用域运算符::
:外部类::嵌套类 对象;
遵循C++访问权限的规定,没有特殊的地方。
外部类是模板类,假设有:
template <class Item> class QueueTP { ... public: class Node { Item item; // 嵌套类中一样使用Item ... } }
嵌套类一样可以使用Item
,没有问题