(虚)继承类的内存大小计算
2014-03-31 22:44
232 查看
今天接触到了虚继承类的大小计算,以前不是很清楚,所以刚开始没想出来,然后百度了一下发现网上各种的博客,然后选了几篇看了下。感觉举的例子大体都是一样的,但是有些地方个人感觉说的不是让人很明白,有点难理解,所以自己重新整理了下,以后忘了可以过来复习一下...
虚函数的工作原理涉及到了虚函数表指针vptr和虚函数表vtbl,当一个对象调用了虚函数,实际的被调用函数通过下面的步骤确定:找到对象的 vptr 指向的 vtbl,然后在 vtbl 中寻找合适的函数指针。如果类定义了虚函数,该类及其派生类就要生成一张虚拟函数表,即vtable。而在类的对象地址空间中存储一个该虚表的入口,占4个字节,这个入口地址是在构造对象时由编译器写入的。所以,由于对象的内存空间包含了虚表入口,编译器能够由这个入口找到恰当的虚函数,这个函数的地址不再由数据类型决定了。因为包含了虚函数的入口(4字节),个人感觉就是个指针。所以我们在计算类的大小的时候就要将其包含在内。
首先来一个不同的类继承的例子,也是众多博主举的例子
下面是虚继承
好了 ,以上是我根据网上资料学习到的
然后我自己修改了下例1中的代码
将E修改为了虚继承,然后我计算出来了E的大小为32,结果电脑跑出来为24,原来我还是没搞明白,然后通过各种调试我大概又知道了,首先不管是多重虚继承还是单一虚继承,指向虚基的指针(注意这边是虚基)只有一个,然后我注意到了E中定义的虚函数,发现其实在B和C中已经定义了,所以E里面没有虚函数表指针,综合这两点,E的大小就是int变量的大小+指向虚基的指针+B的大小+C的大小=24,为了证实我第二点的想法,我将E中虚函数func1修改未func8,然后计算出E大小为28,应该算是验证了我的想法。
另外我回看了一下直接继承的例子,然后尝试修改了E中虚函数的名称,但是发现跟虚函数继承不一样,他没有变化,还是原来的值,我想这也验证了直接继承中虚函数表指针共享的情况.
以上是我的个人理解,如果各位觉得有错误的地方的话欢迎指正.
虚函数的工作原理涉及到了虚函数表指针vptr和虚函数表vtbl,当一个对象调用了虚函数,实际的被调用函数通过下面的步骤确定:找到对象的 vptr 指向的 vtbl,然后在 vtbl 中寻找合适的函数指针。如果类定义了虚函数,该类及其派生类就要生成一张虚拟函数表,即vtable。而在类的对象地址空间中存储一个该虚表的入口,占4个字节,这个入口地址是在构造对象时由编译器写入的。所以,由于对象的内存空间包含了虚表入口,编译器能够由这个入口找到恰当的虚函数,这个函数的地址不再由数据类型决定了。因为包含了虚函数的入口(4字节),个人感觉就是个指针。所以我们在计算类的大小的时候就要将其包含在内。
首先来一个不同的类继承的例子,也是众多博主举的例子
class A { }; class B { char ch; virtual void func0() { } }; class C { char ch1; char ch2; virtual void func() { } virtual void func1() { } }; class D: public A, public C { int d; virtual void func() { } virtual void func1() { } }; class E: public B, public C { int e; virtual void func0() { } virtual void func1() { } }; int main(void) { cout<<"A="<<sizeof(A)<<endl; //result=1 cout<<"B="<<sizeof(B)<<endl; //result=8 cout<<"C="<<sizeof(C)<<endl; //result=8 cout<<"D="<<sizeof(D)<<endl; //result=12 cout<<"E="<<sizeof(E)<<endl; //result=20 return 0; }A大小为1,因为空的类大小默认为1,B的大小为8,char占1字节,补齐之后是4,再加上虚函数表指针。C虽然有两个虚函数,但是只是在虚函数表中添加了一项,虚函数表指针还是1个,所以考虑内存补齐之后大小还为8。E的大小了,因为是普通继承,对于每个对象只有一个VPTR,换句话说他们共享了虚函数表指针,注意这个共享是怎么共享的,我理解的是B和C的虚函数表指针仍然存在,但是E没有了,所以这边E的大小是B+C+int变量的大小为20。
下面是虚继承
class CommonBase { int co; }; class Base1: virtual public CommonBase { public: virtual void print1() { } virtual void print2() { } private: int b1; }; class Base2: virtual public CommonBase { public: virtual void dump1() { } virtual void dump2() { } private: int b2; }; class Derived: public Base1, public Base2 { public: void print2() { } void dump2() { } private: int d; };size(Derived)大小为32,套用各位博主的分析图
class Derived size(32): +--- | +--- (base class Base1) | | {vfptr} | | {vbptr} | | b1 | +--- | +--- (base class Base2) | | {vfptr} | | {vbptr} | | b2 | +--- | d +--- +--- (virtual base CommonBase) | co +---
好了 ,以上是我根据网上资料学习到的
然后我自己修改了下例1中的代码
class A { }; class B { char ch; virtual void func0() { } }; class C { char ch1; char ch2; virtual void func() { } virtual void func1() { } }; class D: public A, public C { int d; virtual void func() { } virtual void func1() { } }; class E:virtual public B, virtual public C { int e; virtual void func0() { } virtual void func1() { } }; int main(void) { cout<<"A="<<sizeof(A)<<endl; //result=1 cout<<"B="<<sizeof(B)<<endl; //result=8 cout<<"C="<<sizeof(C)<<endl; //result=8 cout<<"D="<<sizeof(D)<<endl; //result=12 cout<<"E="<<sizeof(E)<<endl; //result=24 return 0; }
将E修改为了虚继承,然后我计算出来了E的大小为32,结果电脑跑出来为24,原来我还是没搞明白,然后通过各种调试我大概又知道了,首先不管是多重虚继承还是单一虚继承,指向虚基的指针(注意这边是虚基)只有一个,然后我注意到了E中定义的虚函数,发现其实在B和C中已经定义了,所以E里面没有虚函数表指针,综合这两点,E的大小就是int变量的大小+指向虚基的指针+B的大小+C的大小=24,为了证实我第二点的想法,我将E中虚函数func1修改未func8,然后计算出E大小为28,应该算是验证了我的想法。
另外我回看了一下直接继承的例子,然后尝试修改了E中虚函数的名称,但是发现跟虚函数继承不一样,他没有变化,还是原来的值,我想这也验证了直接继承中虚函数表指针共享的情况.
以上是我的个人理解,如果各位觉得有错误的地方的话欢迎指正.
相关文章推荐
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- C++ 06 继承与组合 (has-a is-a) 以及类大小的计算 虚基类对内存模型的影响(不考虑虚函数)
- 三十二、C++内存布局,对象大小计算、虚函数虚继承对类内存模型的影响
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算(转载)
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- 虚函数列表: 取出方法 // 虚函数工作原理和(虚)继承类的内存占用大小计算 32位机器上 sizeof(void *) // 4byte
- C++学习 C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算