C++第十四章笔记

2014/11/26 posted in  C++

第十四章讲的是C++中的代码重用,代码重用是C++的主要目标之一,因此,通过多种继承、模板来实现。

包含

公有继承是is-a关系,也就是说is a type of,可认为是并列关系。但两个类之间不光有并列关系,还是包含关系:has-a关系。那么就又有了包含,私有继承,保护继承。

包含很简单,就是在类的声明中添加一个类的对象作为数据成员。

私有继承

私有继承基类的公有成员和保护成员都将成为派生类的私有成员。这将意味着基类方法将不会成为派生对象的公有接口的一部分,但可以在派生类的成员函数中使用它。

访问基类

通过初始化列表直接调用基类析构函数初始化基类对象,而对于访问基类对象则可以使用强制转换。当然,访问基类对象是在他的可见作用域,派生类的内部实现的。

保护继承

保护继承,基类的公有成员和保护成员都将成为派生类的保护成员。和私有继承一样,基类的接口在派生类中也是可用的,但在继承层次结构之外是不可用的。当派生类派生出另一个类时,私有继承和保护继承之间的主要区别便呈现出来了。使用私有继承时,第三代类将不能使用基类的接口,这是因为基类的公有方法在派生类中将变为私有方法;使用保护继承时,基类的公有方法在第二代中将变成裱糊的,因此第三代派生类可以使用他们。

using重新定义访问权限

对于保护的方法,可以使用using来在public重新定义对外访问权限,定义方法比如:

using std::valarray::min;

来开放min函数的对外权限。

多重继承

多重继承可以让一个类从多个基类继承。

如果多个基类有共同祖先,那么新继承的类中可能有多个相同部分(共同祖先),当然,他们并存而且可以分别访问(通过,对基类的作用域解析运算符),但是大多数情况是不需要的,因此,可以在继承的时候添加virtual,使用虚基类,那么,对于多个虚基类的共同祖先,只会产生一个。

如果是虚基类,在构造函数就不应该用初始化列表调用基类,而应该调用基类的祖先。在虚基类中,这是必须的,但是非虚基类,这是非法的。

因为多重继承经常产生二义性的问题,因此,善用作用域解析运算符。

类模板

C++的类模板为生成通用的类声明提供了一种更好的方法。模板提供参数化类型,既能够将类型名作为参数传递给接收方来建立类或函数。

使用方法,在类的声明和函数的定义(如果是类外定义的话)前加上:

template

类模板可以做基类,可以用作组件类,可以做其他模板的类型参数,可以递归嵌套使用。

模板的具体化

和函数模板一样,可以隐式实例化,显式实例化,显式具体化。甚至可以部分具体化(只支出几个而不是全部参数)。

成员模板

类模板可以作为类的成员或者模板类的成员但在template语句是注意嵌套关系

模板用作参数

模板包含类型参数和非类型参数。模板还可以包含本身就是模板的参数,这种参数是模板新增的特性,用于实现STL。

模板和友元

模板类声明也可以有友元,模板的友元分3类:

  1. 非模板友元,即和模板无关的友元
  2. 约束模板友元,即友元的类型取决于类被实例化的类型
  3. 非约束模板友元,即友元的所有具体化都是类的一个具体化的友元

C++11别名

之前的别名都是通过typedef实现,C++11允许使用using,比如:

using LL = long long;

和typedef相比,不仅可读性更强,而且对于模板的重命名更方便,比如:

template
using arrtype = std::array;


所有的这些机制的目的都是为了让程序员能够重用经过测试的代码,而不用手工复制他们,这样可以简化编程工作,提高程序可靠性!