参考:http://blog.csdn.net/shouhuqi/article/details/7890367
参考:http://baike.baidu.com/view/161302.htm?fr=wordsearch
Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu 转载请标明来源
根据原始定义,知道:
一旦存在虚函数,类中将存在虚函数表,变量中会多一个虚函数表的指针,从而在sizeof时,空间会增大4字节(32位编译情况,64位编译时指针占8字节)
另外还会有一些其他的因素影响,从最下面的代码例子中我们可以看出(32位编译):
1. 虚函数指针位于变量的最前面
证明1:sizeof(ClassParent1) == 24
虚函数指针(4字节):在未设定对齐字节时#pragma pack(n),根据最大变量基本长度对齐的,位于double(8字节)前的变量不足8字节的,因为double按8字节对齐的原因,空出4个字节,也相当于占用了8字节。
Double变量(8字节)
Short变量(2字节),占用两个字节,同时由于struct/class中的最大对齐字节时8字节,结构体整体按8字节对齐,空出6个字节,也相当于占用了8字节。
共计: 8字节+8字节+8字节
证明2:sizeof(ClassParent2) == 16
虚函数指针(4字节)
Short变量(2字节),但由于位于double(8字节)变量前,按照8字节对齐,空出2个字节,共计4个字节
Double变量(8字节)
共计:4+4+8 = 16字节
2. 继承自虚类,再添加虚函数的话,虚函数存在基类虚函数指针指向的虚函数表中
证明1:sizeof(ClassParent1) == sizeof(ClassChild1)
证明1:sizeof(ClassParent2) == sizeof(ClassChild2)
3. 继承自多个虚类的话,并存多个虚函数指针
证明:sizeof(ChildBoth) = 40
分析,分别从基类ClassParent1继承过来一个虚函数指针,又从ClassParent2继承过来一个虚函数指针,所以ChildBoth存有两个虚函数指针。
ChildBoth实例化ClassParent1的虚函数FuncA(),则会修改继承自ClassParent1的虚函数表;实例化ClassParent2的虚函数FuncB(),则会修改继承自ClassParent2的虚函数表。
猜测1:ChildBoth本身添加的虚函数FuncE()存储在继承自第一个基类虚函数指针指向的虚函数表中
#include <iostream> using namespace std; class ClassParent1 { public: double var1; short var2; virtual void FuncA(); virtual void FuncADup(); }; class ClassParent2 { public: short var1; double var2; virtual void FuncB(); virtual void FuncBDup(); };
class ClassChild1 : public ClassParent1 { public: virtual void FuncC(); }; class ClassChild2 : public ClassParent2 { public: virtual void FuncD(); }; class ClassChildBoth : public ClassParent1, ClassParent2 { public: virtual void FuncE(); virtual void FuncA(){}; virtual void FuncB(){}; }; int main() { int nSizeParent1 = sizeof(ClassParent1); int nSizeParent2 = sizeof(ClassParent2); cout<<"Parent1="<<nSizeParent1<<"; Parent2="<<nSizeParent2<<endl; int nSizeChild1 = sizeof(ClassChild1); int nSizeChild2 = sizeof(ClassChild2); int nSizeChildBoth = sizeof(ClassChildBoth); cout<<"Child1="<<nSizeChild1<<"; Child2="<<nSizeChild2<<"; ChildBoth="<<nSizeChildBoth<<endl; getchar(); return 0; }
执行结果: Parent1=24; Parent2=16; Child1=24; Child2=16; ChildBoth=40; |