1 C++中,通过基类的引用(或指针)调用虚函数时,发生动态绑定,两个条件(基类引用或指针、虚函数)缺一不可
虚函数的默认实参将发生静态绑定
2 继承层次的根类一般都需要定义虚析构函数
3 任意非static成员都可以是虚析构函数,static成员函数不能是虚析构函数(应为static成员不是属于某个对象的,而是属于整个类的)
4 protected成员:派生类只能通过派生类对象访问基类的protected成员,派生类对其基类类型对象的protected成员没有特殊的访问权限
private成员:基类的private数据成员在派生类类型的对象中存在,但是派生类没有任何权限访问到基类的private成员
class A { private: int val; }; class B:A { public: void func(){cout << val;} };
func将报错,因为val在派生类中是无权访问的
是否可以理解为:基类中的private和protected成员在基类以外都是能通过基类类型对象来访问的,protected成员在派生类中是可见的,private成员在派生类中是不可见的
5 派生类中的虚函数和基类中的虚函数要保持一致,除非返回类型是基类类型的引用,则派生类中的虚函数返回的可以是及类类型或派生类类型的引用
6 基类类型的指针或引用调用虚函数时,可以通过作用域操作符实现覆盖虚函数动态绑定机制,即指定虚函数的版本
7 接口继承:public继承,即继承了基类的接口
实现继承:protected继承和private继承,即从基类继承的部分并没有称为其接口的一部分,仅仅是便于其内部实现而已
在实现继承中,可以通过在派生类的public声明下声明基类的成员,从而实现这些成员的public继承
8 static成员在整个继承层次中只有一个,如果是private类型,在派生类不能访问。static成员既可以使用作用域操作符来调用,又可以使用箭头操作符来调用
9 派生类中,构造函数总是先构造基类部分,再构造派生类部分,即使派生类构造函数初始化列表中没有基类构造函数,也将先调用基类的默认构造函数,构造基类部分
派生类构造函数初始化列表中,只能初始化自己的直接基类(尊重基类接口)
10 派生类析构函数:派生类析构函数不负责撤销基类对象的成员,编译器总是显式调用派生类对象基类部分的析构函数,每个析构函数只负责清理自己的成员
对象的撤销顺序与构造顺序相反,首先执行派生类析构函数,然后按继承层次依次向上调用各基类析构函数
11 虚析构函数:
派生类自动调用基类析构函数撤销基类部分对基类的设计有重要的影响
删除指向动态分配对象的指针时,在释放对象的内存之前,需要运行对象的析构函数。可是指针的静态类型可能与被删除对象的动态类型不同(可能会删除实际指向派生类对象的基类类型的指针),因此基类的析构函数要为虚析构函数,保证析构函数的动态绑定
12 纯虚函数:
在虚函数形参表后面添上=0可以将虚函数定义为纯虚函数,含有(或继承)一个或多个纯虚函数的类称为抽象基类,抽象类不能创建对象
如果一个类没有将从基类继承来的虚函数声明为纯虚函数,同时类没有实现自己的虚函数版本,则指向该类的指针动态调用虚函数时将使用继承类的虚函数版本,这可能不满足该类的用户调用该函数时的期望,所以将该函数声明为纯虚函数,这样将不能创建该类的对象
13 句柄类
C++面向对象编程,却不能使用对象本身来支持面向对象编程,而必须使用指针或引用
通用的技术是定义句柄类,句柄类存储和管理基类的指针,句柄的用户可以获得动态行为。