- 非静态数据成员在对象之内
- 静态数据成员在对象之外
- 静态、非静态成员函数在对象之外
- 类中存在虚函数时,一个类对应一个virtual table放在对象之外,对象中安插一个指针vptr指向这个表。
测试例程:
#include <iostream> using namespace std; class A { public: int x, y; static int s; void f1() { } static void f2() { } virtual void f3() { } }; int A::s = 123; int main() { cout << "size = " << sizeof(A); return 0; }
运行结果:
可以看出,对象所在内存中只包含有整型变量x、y、vptr,其它成员全部存在于对象之外。
下面讨论继承体系下的对象模型。下面这个测试例程有点意思:
#include <iostream> using namespace std; class A { public: int x, y; }; class B: public A { }; class C: virtual public A { }; int main() { cout << "class B size = " << sizeof(B) << endl; cout << "class C size = " << sizeof(C) << endl; return 0; }
运行结果:
类C采用了虚继承,内部就多了四字节。这是由于虚继承的特性决定的:在虚拟继承情况下,基类(虚基类)不管在继承链中被派生多少次,永远只会存在一个实例。和virtual table类似,也存在一个指针表(virtual base class table),表中每个指针指向一个虚基类地址,在对象中也安插一个指针指向这个表。所以类C才会增加了四字节空间。而在普通继承中,派生对象把基类对象包裹起来存放一块连续内存中,每个类都有一份基类对象的实例。
参考:
《深度探索C++对象模型》 P9-P13.