(c++常问问题十一)sizeof一个类
下面直接上代码说明:
1.当sizeof一个空类(结构体):
class base { public: base(); base(int n); }; class node : public base { node(); node(int n):base(n) { //... } }; struct MyStruct { }; void main() { cout<<sizeof(base)<<endl;//输出结果为:1 cout<<sizeof(node)<<endl;//输出结果为:1 cout<<sizeof(MyStruct)<<endl;//输出结果为:1 system("pause"); }
因为一个空类也要实例化,所谓类的实例化就是在内存中分配一块地址,每个实例在内存中都有独一无二的地址。
同样空类也会被实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。(结构体也适用)
2.当一个空类里面有虚拟函数
class base { public: base(); virtual void getSomeThing(); }; class node : public base { node(); }; void main() { cout<<sizeof(base)<<endl;//结果为4 cout<<sizeof(node)<<endl;//结果为4 system("pause"); }
base中有个虚函数,那就存在个V表,V表中存放一个虚指针来记录这个函数。32位下指针的大小为4.
class base { public: base(); virtual void getSomeThing(); }; class node : public base { node(); virtual void getSomeTime(); }; void main() { cout<<sizeof(base)<<endl;//输出结果4 cout<<sizeof(node)<<endl;//输出结果4 system("pause"); }
当子类去继承有V表的基类时,虽然他们的虚拟函数不一样,但是他们能公用一个指针,所以结果也是4
3.当基类是虚基类的时候,他们就不能公用V表了(前面我的文章有专门介绍)
class base { public: base(); virtual void getSomeThing(); }; class node : virtual public base { node(); virtual void getSomeTime(); char a; }; void main() { cout<<sizeof(base)<<endl;//输出结果4 cout<<sizeof(node)<<endl;//输出结果16 system("pause"); }
分析:
base因为有V表,所以他的长度为32位系统下一个long的长度,所以结果为4
node的16是怎么来的呢?(base的V表=4 , 虚拟继承基类的指针=4 ,自己的V表=4 , 由于字节对齐的原因char填充以后把长度补满为最长长度(long)的倍数=16)