继承
1.普通继承(不包含虚函数)
a.单继承
class Parent { }; class Sub : public Parent { };
b.多继承
class Parent1 { }; class Parent2 { }; class Sub : public Parent1, public Parent2 { };
c.菱形继承
class Parent { }; class Parent1 : public Parent { }; class Parent2 : public Parent { }; class Sub : public Parent1, public Parent2 { };
C++对象模型:正在使用的
在此模型下,nonstatic 数据成员被置于每一个类对象中,而static数据成员被置于类对象之外。static与nonstatic函数也都放在类对象之外,而对于virtual 函数,则通过虚函数表+虚指针来支持:
(1)每个类生成一个表格,称为虚表(virtual table,简称vtbl)。虚表中存放着一堆指针,这些指针指向该类每一个虚函数。虚表中的函数地址将按声明时的顺序排列
(2)每个类对象都拥有一个虚表指针(vptr),由编译器为其生成。虚表指针的设定与重置皆由类的复制控制(也即是构造函数、析构函数、赋值操作符)来完成。vptr的位置为编译器决定,传统上它被放在所有显示声明的成员之后,不过现在许多编译器把vptr放在一个类对象的最前端(也就是说对象的地址就是vptr的地址)
(3)虚函数表的前面设置了一个指向type_info的指针,用以支持RTTI(Run Time Type Identification,运行时类型识别)。RTTI是为多态而生成的信息,包括对象继承关系,对象本身的描述等,只有具有虚函数的对象在会生成。
单继承(父类含虚函数)
原则:
(1)子类与父类拥有各自的一个虚函数表
(2)若子类并无overwrite父类虚函数,用父类虚函数
(3)若子类重写(overwrite)了父类的虚函数,则子类虚函数将覆盖虚表中对应的父类虚函数
(4)若子声明了自己新的虚函数,则该虚函数地址将扩充到虚函数表最后
一般多继承(不考虑菱形继承)
(1)若子类新增虚函数,放在声明的第一个父类的虚函数表中
(2)若子类重写了父类的虚函数,所有父类的虚函数表都要改变:如fun1
(3)内存布局中,父类按照其声明顺序排列