参考:
1、http://hi.baidu.com/scarlettgy/item/1cc4500a21f41be4fe240d73,讲解了一般的虚指针中虚函数表的建立过程(包括单继承、多继承)
2、http://blog.csdn.net/hackbuteer1/article/details/7883531,讲解了虚继承的不同处理。
计算类的内存空间占有的方法:(从最里层的类算起)
计算基类的内存占有数
(有虚函数,增加4个字节的指向虚函数表的指针,加上类成员的内存占有数)
派生类
(当本类或者基类有虚函数时)
(一般继承4个字节(指向本身虚继承表的指针)、虚继承8个字节(指向本身虚继承表的指针和指向基类虚函数表的指针))
(当没有虚函数时)
(不计算这类指针的内存)
最后,计算类自身的数据成员的内存占有。
考虑内存对齐问题。
一般继承:
1 #include <iostream> 2 using namespace std; 3 4 class C180 5 { 6 public: 7 8 C180() { 9 foo(); 10 this->foo(); 11 } 12 virtual void foo() { 13 cout << "<< C180.foo this: " << this << " vtadr: " << *(void**)this << endl; 14 } 15 }; 16 17 class C190 : public C180 18 { 19 public: 20 21 C190() {} 22 virtual void foo() { 23 cout << "<< C190.foo this: " << this << " vtadr: " << *(void**)this << endl; 24 } 25 virtual void goo() {} 26 }; 27 28 void main () 29 { 30 C180 obj180; 31 C190 obj190; 32 //obj.foo(); 33 34 cout << sizeof(obj180) << endl; 35 cout << sizeof(obj190) << endl; 36 }
1 class C190 size(4): 2 | +--- 3 | +--- (base class C180) // C180 4 | | {vfptr} 5 //C180没有基类结束 6 +---
基类C180:4个字节;
派生类C190:4个字节;// 没有增加字节,只是改变了基类的虚函数表的内存布局数据
虚继承:
1 class CommonBase 2 { 3 int co; 4 }; 5 6 class Base1: virtual public CommonBase 7 { 8 public: 9 virtual void print1() { } 10 virtual void print2() { } 11 private: 12 int b1; 13 }; 14 15 class Base2: virtual public CommonBase 16 { 17 public: 18 virtual void dump1() { } 19 virtual void dump2() { } 20 private: 21 int b2; 22 }; 23 24 class Derived: public Base1, public Base2 25 { 26 public: 27 void print2() { } 28 void dump2() { } 29 private: 30 int d; 31 };
class Derived size(32): +--- | +--- (base class Base1) | | {vfptr} //4 | | {vbptr} //4 | | b1 //4 | +--- | +--- (base class Base2) | | {vfptr} //4 | | {vbptr} //4 | | b2 //4 | +--- | d //4 +--- +--- (virtual base CommonBase) //虚继承的基类只算一次,且放到最后算 | co //4 +---
32字节