C++ class 相对于 C struct,支持了更多特性,如添加了类的方法,构造析构函数,继承等。一般来说 class 和 struct 效率大部分情况下是相同的,引起效率差异的地方主要在两点:
virutal function。class需要维护一个虚函数表,并通过虚指针指向它,中间多了一道访问转换。
virutal base class。虚基类,主要是为了解决菱形继承关系,防止基类对象在子类对象布局中存在多份,因而引入了指针,这中间也多了一道访问转换。
C++对象模型
非静态成员变量
非静态成员变量存放在每个object上
静态成员变量
静态成员变量存放在静态数据区,需要在类外单独定义。例如
1 | class A { |
成员函数
成员函数,包括非静态和静态成员函数,存放于代码区,也是独立于每个object之外。
虚函数
所有的虚函数被放在类的虚函数表里,虚函数表由编译器生成;每个object有个指向虚函数表的指针,在运行时由构造函数、析构函数、赋值操作符来设置或者重置。
TypeInfo
类的类型信息,用来在运行时支持类型识别 (RTTI),也存放在虚函数表里,通常放在虚表的第一个slot。
总览
未涉及继承的class对象布局,总体的示意图就类似下面这样
C++多态语义
c++多态从语法上说,需要的形式是基类指针或者引用指向子类对象,如
1 | Derived d; |
如果直接将子类对象直接赋值给基类对象,则子类对象会被截断:
1 | Base b; |
因此,如果有一个基类的指针*bp
或者引用 bi
,我们必然不能确定该指针或引用指向的是什么,可能是基类的对象,也可能是子类的对象,因此其调用的方法必须在运行时确定,这也是多态的具体表现。
但是也要注意,并不是任意一个指针或者引用就支持指针,比如下面
1 | // no polymorphism |
以下是多态语法形式的内存布局:
更复杂的形式: