14.1.包含对象成员的类
-
valarray类是由头文件valarray支持的。用于处理数值,它支持诸如数组中所有元素的值以及在数组中找出最大和最小的值等操作,valarray被定义为一个模板类,以便能够处理不同的数据类型
-
模板特性意味着声明对象时,必须指定具体的数据类型
valarray weights;
该类的一些方法
C++和约束
- C++包含让程序员能够限制程序结构的特性–使用explict防止单参数构造函数的隐式转换,使用const限制方法修改数据等等,根本原因:在编译阶段出现错误优于在运行阶段出现错误
- 当初始化列表中包含多个项目时,这些项目被初始化的顺序为它们被声明的顺序,而不是它们在初始化列表中的顺序
14.2 私有继承
- 使用多个基类的继承被称为多重继承
- 使用私有继承时将使用类名和作用域解析运算符来调用方法
- 使用强制类型转换访问基类对象
- 通过显式地转换为基类来访问基类的友元函数
- 在私有继承中,未进行显示类型转换的派生类引用或指针,无法赋值给基类的引用或指针
- 保护继承:使用一个using声明来指出派生类可以使用特定的基类成员,即使采用的是私有派生
14.3 多重继承
- 虚基类使得从多个类派生出的对象只继承一个基类对象
- 通过来类声明中使用关键字virtual,可以使Worker用作Singer和Waiter的虚基类
class Singer : public virtual Worker { . . . }
class Waiter: public virtual Worker{ … } - C++在基类是虚的时,禁止信息通过中间类自动传递给基类。然而,编译器必须在构造派生对象之前构造基类对象组件;在上述情况下,编译器将使用Worker的默认构造函数,如果不希望默认构造函数来构造虚基类对象,则需要显示地调用所需的基类构造函数
- 如果基类是虚基类,派生类将包含基类的一个子对象,如果基类不是虚基类,派生类将包含多个子对象。当类通过多条虚途径和非虚途径继承某个特定的基类时,该类将包含一个表示所有的虚途径的基类子对象和分别表示各条非虚途径的多个基类子对象
14.4 类模板
template
可以使用自己的泛型名替代Type
- 仅在程序包含模板并不能生成模板类,而必须请求实例化,为此,需要声明一个类型为模板类的对象,方法是使用所需的具体类型替换泛型名
Stack kernels; - 泛型标识符–称为类型参数,意味着它们类似于变量,但赋给它们的不能是数字,而只能是类型。注意,必须显式地提供所需的类型,这与常规的函数模板是不同的,因为编译器可以根据函数的参数类型来确认要生成那种函数
模板的具体化
- 隐式实例化,即它们声明一个或多个对象,指出所需的类型,而编译器使用通用模板提供的处方生成具体的类定义
ArrayTP<double, 30> * pt; - 显式实例化,当使用关键字template并指出所需类型来声明类时,编译器将生成类声明的显式实例化,声明必须位于模板定义所在的名称空间中
template class ArrayTP<string, 100> - 模板可以包含类型参数和非类型参数。模板还可以包含本身就是模板的参数,这种参数式模板新增的特性,用于实现STL
模板类声明也可以有友元
- 非模板友元
- 约束模板友元,即友元的类型取决于类被实例化时的类型
template void counts();
template void report(T &t)
template
class HasFriendT
{
friend void counts();
friend void report<>(HasFriendT &);
} - 非约束模板友元,即友元的所有具体化都是类的每一个具体化的友元
template
class ManyFriend
{
template <typename C, typename D> friend void show2(C &, D &);
}
模板别名
typedef std::array<double, 12> arrd;