8/4 15.1~15.2 C++ 友元、嵌套类

Posted by 橙叶 on Mon, Aug 5, 2019

想了好久还是用这种方式水一水了。其实C++ Primer Plus并不适合有编程基础之后去读,不过懒得再找书了。学C++的过程中很尴尬的一点是实践机会不多,这样也能尽可能避免过目就忘的情况,权当笔记,会摘抄书中的一些代码。

先从第15章开始。

15.1 友元

15.1.1 友元类

使用友元类适合这样的关系:友元类需要访问原始类的私有部分,两个类是亲密的伙伴关系而不是“服务器-客户端”的关系,使用友元类需要原始类的同意(即原始类声明中的friend),意味着友元类和原始类同时产生。典型的例子就是书中的电视和遥控器的关系。

在原始类的声明中指定友元类,使用friend class 类名来实现。

友元类的特点

[ssbluelist]

  • 友元类可以访问原始类的私有成员和保护成员
  • 友元声明可以位于公有、私有或保护部分,没有区别
[/ssbluelist]

15.1.2 友元成员函数

相比于上面将整个类都作为友元,友元成员函数“只信任类的一部分”,使用作用域解析来指定类中的某个方法。

class Tv
{
      friend void Remote::set_chan(Tv & t, int c);
}
要点 向前声明(forward declaration)

作用域解析运算符::左边是一个类,但是要让编译器知道这是一个类而不是别的什么(比如命名空间),需要将含有友元成员函数的类声明放到原始类声明前面,但这个成员函数在声明中又不可避免地使用到原始类,又需要把它放到后面。

解决方法是向前声明,将友元成员函数所在的类声明放在前面,在它的前面再加一句class 原始类指出::左边是一个类。

这样的话,友元成员函数就不要使用内联代码,因为如果把实现写在了声明里,当编译器走到实现的时候并不知道原始类有什么方法。应当把友元成员函数的定义放到原始类声明之后。(总结一句话:友元成员函数不能内联,类中只包含友元成员函数的声明)

仍然要将友元成员函数作为内联方法,在方法定义前加inline

15.1.3 其它友元关系

成为彼此的友元

假设原始类要访问友元类的私有/保护成员,那么需要让原始类成为友元类的友元,也就是互为friend

与前面类似,定义统统放到声明后面。

15.1.4 共同的友元

一个函数可以是两个类的友元,同样,这两个类在声明的时候一定会出现一个先于另一个提到后者,那么也要使用向前声明。

总之,一定要让编译器获得足够的信息,在提到一个类之前必须表明它是个类。使用向前声明,让尚未正式声明的类提前强调自己的身份。

在类中声明友元类时使用friend class 友元类class表明跟在它后面的是一个类,所以不需要向前声明。

15.2 嵌套类

包含和嵌套类很容易区分,前者是在类中使用别的类对象(对象是成员),后者是在类中定义类(嵌套类是成员)。

15.2.1 嵌套类和访问权限

在外部使用嵌套类,用到作用域运算符::外部类::嵌套类 对象;

遵循C++访问权限的规定,没有特殊的地方。

15.2.2 模板中的嵌套

外部类是模板类,假设有:

template <class Item>
class QueueTP
{
   ...
   public:
     class Node {
       Item item;  // 嵌套类中一样使用Item
       ...
     }
}

嵌套类一样可以使用Item,没有问题



comments powered by Disqus