15.1 概述
派生类与基类的关系类似于:是一种;
类型之间的关系类似于:有一个。
1.OOP的核心思想是数据抽象、继承和动态绑定。(多态性)
使用数据抽象,可以将类的接口与实现分离;
使用继承,可以定义相似的类型并对其相似关系建模;
使用动态绑定,可以在一定程度上忽略相似类型的区别,而以统一的方式使用它们的对象。
2.动态绑定
又被称为运行时绑定,即函数的运行版本由实参决定,在运行时选择函数的版本。
3.作为继承关系中根节点的类通常都会定义一个虚析构函数。
4.访问控制与继承
派生类可以继承定义在基类中的成员,但是派生类的成员函数不一定有权访问从基类继承而来的成员;
派生类能访问公有成员,而不能访问私有成员;
基类希望它的派生类有权访问该成员,同时禁止其他用户访问,这些成员我们用protected访问运算符来说明。
5.派生类构造函数
a.每个类控制它自己的成员初始化过程。
b.派生类对象不能直接初始化基类的成员,应该遵循基类的接口,并且通过调用基类的构造函数来初始化那些从基类中继承而来的成员。
6.如果基类定义了一个静态成员,则在整个继承体系中只存在该成员的唯一定义。
7.防止继承的发生,即在类名后跟一个关键字final
8.继承关系的类型之间的转换规则
a.从派生类到基类的类型转换只对指针或引用类型有效
b.基类向派生类不存在隐式类型转换
c.派生类向基类的类型转换也可能会由于访问受限而变得不可行。
9.我们不能创建抽象基类(含有纯虚函数的类)的对象。
10.受保护的成员
a.受保护的成员对于类的用户是不可访问的
b.受保护的成员对于派生类的成员和友元来说是可访问的
c.派生类的成员或友元只能通过派生类对象来访问基类的受保护成员。派生类对于一个基类对象中的受保护成员没有任何访问特权。
11.友元与继承
a.友元关系不能传递,友元关系同样也不能继承。基类的友元在访问派生类成员时不具有特殊性,类似的派生类的友元也不能访问基类的成员。
b.对基类的访问权限由基类本身控制,即使对于派生类的基类部分也是如此。
12.默认的继承保护级别
使用class关键字定义的派生类是私有继承;而使用struct关键字定义的派生类是公有继承的。事实上,二者唯一的差别就是默认成员访问说明符和默认派生访问说明符不同。
13.虚析构函数将阻止合成移动操作
14.派生类的拷贝控制成员
派生类的构造函数再起初始化阶段不仅要初始化派生类自己的成员,还负责初始化派生类对象的基类部分。
而析构函数只负责销毁派生类自己分配的资源。
派生类的拷贝和移动构造函数,赋值运算符等都需要显示地为其基类部分赋值。
通常情况下,using声明语句只是令某个名字在当前作用域内可见。而当作用于构造函数时,using声明语句将令编译器产生代码。
15.容器与继承
当我们使用容器存储继承体系中的对象时,通常必须采取间接存储的方式。因为不允许在容器中保存不同类型的元素。我们可以在容器中存智能指针而非对象。
我们可以讲一个派生类的普通指针转换成基类指针,也可以将派生类的智能指针转换成基类的智能指针。