C++类的成员变量在内存中的布局
首先这个内存布局是可以通过编译器在编译的时候进行观测的,使用VC 编译的这个结果类似于图形化 更加直观。
在解决方案的C文件上右键单击 选择属性-》C/C+±》命令行-》然后在底下的其他选项中输入/d1 reportAllClassLayout
即可。然后在写完代码后直接用生成
选项进行编译就能得到类的内存布局。
单独一个类,包含了虚函数
class Base {
int a;
int b;
public:
virtual void VirtualFunction();
};
输出结果是
>class Base size(12):
1> +---
1> 0 | {vfptr} //这是指向虚函数的指针
1> 4 | a
1> 8 | b
1> +---
1>Base::$vftable@:
1> | &Base_meta
1> | 0
1> 0 | &Base::VirtualFunction
1>Base::VirtualFunction this adjustor: 0
子类public继承父类,并添加了一个新的虚函数
class Base {
int a;
int b;
public:
virtual void VirtualFunction();
};
class DerivedClass : public Base {
int c;
public:
virtual void Derivedcommonfunction();
};
1>class Base size(12):
1> +---
1> 0 | {vfptr}
1> 4 | a
1> 8 | b
1> +---
1>Base::$vftable@:
1> | &Base_meta
1> | 0
1> 0 | &Base::VirtualFunction
1>Base::VirtualFunction this adjustor: 0
1>class DerivedClass size(16):
1> +---
1> 0 | +--- (base class Base)
1> 0 | | {vfptr}
1> 4 | | a
1> 8 | | b
1> | +---
1>12 | c
1> +---
1>DerivedClass::$vftable@:
1> | &DerivedClass_meta
1> | 0
1> 0 | &Base::VirtualFunction // 因为没有修改过父类的虚函数 所以这个还是指向父类虚函数的位置
1> 1 | &DerivedClass::Derivedcommonfunction // 这是在父类的虚函数表后面添加的子类的虚函数
1>DerivedClass::Derivedcommonfunction this adjustor: 0
如果是子类public继承 并重写了父类虚函数
class Base {
int a;
int b;
public:
virtual void VirtualFunction();
};
class DerivedClass : public Base {
int c;
public:
virtual void VirtualFunction();
};
1>class Base size(12):
1> +---
1> 0 | {vfptr}
1> 4 | a
1> 8 | b
1> +---
1>Base::$vftable@:
1> | &Base_meta
1> | 0
1> 0 | &Base::VirtualFunction
1>Base::VirtualFunction this adjustor: 0
1>class DerivedClass size(16):
1> +---
1> 0 | +--- (base class Base)
1> 0 | | {vfptr}
1> 4 | | a
1> 8 | | b
1> | +---
1>12 | c
1> +---
1>DerivedClass::$vftable@:
1> | &DerivedClass_meta
1> | 0
1> 0 | &DerivedClass::VirtualFunction // 因为子类重写了父类的这个虚函数,所以在这里指向了其他位置,但是没有被重写的虚函数是不受影响的
1>DerivedClass::VirtualFunction this adjustor: 0
如果子类是virtual public继承父类,并且重写父类虚函数
class Base {
int a;
int b;
public:
virtual void VirtualFunction();
};
class DerivedClass : virtual public Base {
int c;
public:
virtual void VirtualFunction();
};
1>class Base size(12):
1> +---
1> 0 | {vfptr}
1> 4 | a
1> 8 | b
1> +---
1>Base::$vftable@:
1> | &Base_meta
1> | 0
1> 0 | &Base::VirtualFunction
1>Base::VirtualFunction this adjustor: 0
1>class DerivedClass size(20):
1> +---
1> 0 | {vbptr} // 子类的虚函数指针
1> 4 | c
1> +---
1> +--- (virtual base Base)
1> 8 | {vfptr} // 父类的虚函数指针
1>12 | a
1>16 | b
1> +---
1>DerivedClass::$vbtable@:
1> 0 | 0
1> 1 | 8 (DerivedClassd(DerivedClass+0)Base) // 这个应该是定位到了父类的虚函数表,因为是重写父类虚函数
1>DerivedClass::$vftable@:
1> | -8 // 这个可能是父类虚函数指针到子类虚函数指针的偏移
1> 0 | &DerivedClass::VirtualFunction
1>DerivedClass::VirtualFunction this adjustor: 8
1>vbi: class offset o.vbptr o.vbte fVtorDisp
1> Base 8 0 4 0
子类virtual public继承父类之后,添加新的虚函数
class Base {
int a;
int b;
public:
virtual void VirtualFunction();
};
class DerivedClass : virtual public Base {
int c;
public:
virtual void Derivedcommonfunction1();
};
1>class Base size(12):
1> +---
1> 0 | {vfptr}
1> 4 | a
1> 8 | b
1> +---
1>Base::$vftable@:
1> | &Base_meta
1> | 0
1> 0 | &Base::VirtualFunction
1>Base::VirtualFunction this adjustor: 0
1>class DerivedClass size(24):
1> +---
1> 0 | {vfptr} // 指向子类自己的虚函数表
1> 4 | {vbptr} // 这个感觉是专门用来指向父类虚函数指针的,因为他的表里总是指向父类虚函数表
1> 8 | c
1> +---
1> +--- (virtual base Base)
1>12 | {vfptr} // 指向父类的虚函数表
1>16 | a
1>20 | b
1> +---
1>DerivedClass::$vftable@DerivedClass@:
1> | &DerivedClass_meta
1> | 0
1> 0 | &DerivedClass::Derivedcommonfunction1
1>DerivedClass::$vbtable@:
1> 0 | -4
1> 1 | 8 (DerivedClassd(DerivedClass+4)Base)
1>DerivedClass::$vftable@Base@:
1> | -12
1> 0 | &Base::VirtualFunction
1>DerivedClass::Derivedcommonfunction1 this adjustor: 0
1>vbi: class offset o.vbptr o.vbte fVtorDisp
1> Base 12 4 4 0
以virtual public继承基类,然后以public方式多继承(不自定义虚函数)
class Base {
int a;
int b;
public:
virtual void VirtualFunction();
};
class DerivedClass1 : virtual public Base {
int c;
public:
virtual void Derivedcommonfunction1();
};
class DerivedClass2 : virtual public Base {
int c;
public:
virtual void Derivedcommonfunction1();
};
class DerivedClass3 : public DerivedClass1,public DerivedClass2 {
int c;
public:
virtual void Derivedcommonfunction1();
};
1>class Base size(12):
1> +---
1> 0 | {vfptr}
1> 4 | a
1> 8 | b
1> +---
1>Base::$vftable@:
1> | &Base_meta
1> | 0
1> 0 | &Base::VirtualFunction
1>Base::VirtualFunction this adjustor: 0
1>class DerivedClass1 size(24):
1> +---
1> 0 | {vfptr}
1> 4 | {vbptr}
1> 8 | c
1> +---
1> +--- (virtual base Base)
1>12 | {vfptr}
1>16 | a
1>20 | b
1> +---
1>DerivedClass1::$vftable@DerivedClass1@:
1> | &DerivedClass1_meta
1> | 0
1> 0 | &DerivedClass1::Derivedcommonfunction1
1>DerivedClass1::$vbtable@:
1> 0 | -4
1> 1 | 8 (DerivedClass1d(DerivedClass1+4)Base)
1>DerivedClass1::$vftable@Base@:
1> | -12
1> 0 | &Base::VirtualFunction
1>DerivedClass1::Derivedcommonfunction1 this adjustor: 0
1>vbi: class offset o.vbptr o.vbte fVtorDisp
1> Base 12 4 4 0
...//DerivedClass2 和 DerivedClass1 是一样的 这里省略了
1>class DerivedClass3 size(40):
1> +---
1> 0 | +--- (base class DerivedClass1)
1> 0 | | {vfptr}
1> 4 | | {vbptr}
1> 8 | | c
1> | +---
1>12 | +--- (base class DerivedClass2)
1>12 | | {vfptr}
1>16 | | {vbptr}
1>20 | | c
1> | +---
1>24 | c
1> +---
1> +--- (virtual base Base)
1>28 | {vfptr}
1>32 | a
1>36 | b
1> +---
1>DerivedClass3::$vftable@DerivedClass1@:
1> | &DerivedClass3_meta
1> | 0
1> 0 | &DerivedClass3::Derivedcommonfunction1
1>DerivedClass3::$vftable@DerivedClass2@:
1> | -12
1> 0 | &thunk: this-=12; goto DerivedClass3::Derivedcommonfunction1
1>DerivedClass3::$vbtable@DerivedClass1@:
1> 0 | -4
1> 1 | 24 (DerivedClass3d(DerivedClass1+4)Base)
1>DerivedClass3::$vbtable@DerivedClass2@:
1> 0 | -4
1> 1 | 12 (DerivedClass3d(DerivedClass2+4)Base)
1>DerivedClass3::$vftable@Base@:
1> | -28
1> 0 | &Base::VirtualFunction
1>DerivedClass3::Derivedcommonfunction1 this adjustor: 0
1>vbi: class offset o.vbptr o.vbte fVtorDisp
1> Base 28 4 4 0
如果全部都是虚继承(不自定义虚函数)
class Base {
int a;
int b;
public:
virtual void VirtualFunction();
};
class DerivedClass1 : virtual public Base {
int c;
public:
virtual void Derivedcommonfunction1();
};
class DerivedClass2 : virtual public Base {
int c;
public:
virtual void Derivedcommonfunction1();
};
class DerivedClass3 : virtual public DerivedClass1, virtual public DerivedClass2 {
int c;
public:
virtual void Derivedcommonfunction1();
};
1>class Base size(12):
1> +---
1> 0 | {vfptr}
1> 4 | a
1> 8 | b
1> +---
1>Base::$vftable@:
1> | &Base_meta
1> | 0
1> 0 | &Base::VirtualFunction
1>Base::VirtualFunction this adjustor: 0
1>class DerivedClass1 size(24):
1> +---
1> 0 | {vfptr}
1> 4 | {vbptr}
1> 8 | c
1> +---
1> +--- (virtual base Base)
1>12 | {vfptr}
1>16 | a
1>20 | b
1> +---
1>DerivedClass1::$vftable@DerivedClass1@:
1> | &DerivedClass1_meta
1> | 0
1> 0 | &DerivedClass1::Derivedcommonfunction1
1>DerivedClass1::$vbtable@:
1> 0 | -4
1> 1 | 8 (DerivedClass1d(DerivedClass1+4)Base)
1>DerivedClass1::$vftable@Base@:
1> | -12
1> 0 | &Base::VirtualFunction
1>DerivedClass1::Derivedcommonfunction1 this adjustor: 0
1>vbi: class offset o.vbptr o.vbte fVtorDisp
1> Base 12 4 4 0
1>class DerivedClass3 size(44):
1> +---
1> 0 | {vbptr}
1> 4 | c
1> +---
1> +--- (virtual base Base)
1> 8 | {vfptr}
1>12 | a
1>16 | b
1> +---
1> +--- (virtual base DerivedClass1)
1>20 | {vfptr}
1>24 | {vbptr}
1>28 | c
1> +---
1> +--- (virtual base DerivedClass2)
1>32 | {vfptr}
1>36 | {vbptr}
1>40 | c
1> +---
1>DerivedClass3::$vbtable@DerivedClass3@:
1> 0 | 0
1> 1 | 8 (DerivedClass3d(DerivedClass3+0)Base)
1> 2 | 20 (DerivedClass3d(DerivedClass3+0)DerivedClass1)
1> 3 | 32 (DerivedClass3d(DerivedClass3+0)DerivedClass2)
1>DerivedClass3::$vftable@Base@:
1> | -8
1> 0 | &Base::VirtualFunction
1>DerivedClass3::$vftable@DerivedClass1@:
1> | -20
1> 0 | &DerivedClass3::Derivedcommonfunction1
1>DerivedClass3::$vbtable@DerivedClass1@:
1> 0 | -4
1> 1 | -16 (DerivedClass3d(DerivedClass1+4)Base)
1>DerivedClass3::$vftable@DerivedClass2@:
1> | -32
1> 0 | &thunk: this-=12; goto DerivedClass3::Derivedcommonfunction1
1>DerivedClass3::$vbtable@DerivedClass2@:
1> 0 | -4
1> 1 | -28 (DerivedClass3d(DerivedClass2+4)Base)
1>DerivedClass3::Derivedcommonfunction1 this adjustor: 20
1>vbi: class offset o.vbptr o.vbte fVtorDisp
1> Base 8 0 4 0
1> DerivedClass1 20 0 8 0
1> DerivedClass2 32 0 12 0
如果都不是虚继承
class Base {
int a;
int b;
public:
virtual void VirtualFunction();
};
class DerivedClass1 : public Base {
int c;
public:
virtual void Derivedcommonfunction1();
};
class DerivedClass2 : public Base {
int c;
public:
virtual void Derivedcommonfunction1();
};
class DerivedClass3 : public DerivedClass1, public DerivedClass2 {
int c;
public:
virtual void Derivedcommonfunction1();
};
1>class Base size(12):
1> +---
1> 0 | {vfptr}
1> 4 | a
1> 8 | b
1> +---
1>Base::$vftable@:
1> | &Base_meta
1> | 0
1> 0 | &Base::VirtualFunction
1>Base::VirtualFunction this adjustor: 0
1>class DerivedClass1 size(16):
1> +---
1> 0 | +--- (base class Base)
1> 0 | | {vfptr}
1> 4 | | a
1> 8 | | b
1> | +---
1>12 | c
1> +---
1>DerivedClass1::$vftable@:
1> | &DerivedClass1_meta
1> | 0
1> 0 | &Base::VirtualFunction
1> 1 | &DerivedClass1::Derivedcommonfunction1
1>DerivedClass1::Derivedcommonfunction1 this adjustor: 0
1>class DerivedClass3 size(36):
1> +---
1> 0 | +--- (base class DerivedClass1)
1> 0 | | +--- (base class Base)
1> 0 | | | {vfptr}
1> 4 | | | a
1> 8 | | | b
1> | | +---
1>12 | | c
1> | +---
1>16 | +--- (base class DerivedClass2)
1>16 | | +--- (base class Base)
1>16 | | | {vfptr}
1>20 | | | a
1>24 | | | b
1> | | +---
1>28 | | c
1> | +---
1>32 | c
1> +---
1>DerivedClass3::$vftable@DerivedClass1@:
1> | &DerivedClass3_meta
1> | 0
1> 0 | &Base::VirtualFunction
1> 1 | &DerivedClass3::Derivedcommonfunction1
1>DerivedClass3::$vftable@DerivedClass2@:
1> | -16
1> 0 | &Base::VirtualFunction
1> 1 | &thunk: this-=16; goto DerivedClass3::Derivedcommonfunction1
1>DerivedClass3::Derivedcommonfunction1 this adjustor: 0
如果只有一个是虚继承
class Base {
int a;
int b;
public:
virtual void VirtualFunction();
};
class DerivedClass1 : virtual public Base {
int c;
public:
virtual void Derivedcommonfunction1();
};
class DerivedClass2 : public Base {
int c;
public:
virtual void Derivedcommonfunction1();
};
class DerivedClass3 : public DerivedClass1, public DerivedClass2 {
int c;
public:
virtual void Derivedcommonfunction1();
};
1>class Base size(12):
1> +---
1> 0 | {vfptr}
1> 4 | a
1> 8 | b
1> +---
1>Base::$vftable@:
1> | &Base_meta
1> | 0
1> 0 | &Base::VirtualFunction
1>Base::VirtualFunction this adjustor: 0
1>class DerivedClass1 size(24):
1> +---
1> 0 | {vfptr}
1> 4 | {vbptr}
1> 8 | c
1> +---
1> +--- (virtual base Base)
1>12 | {vfptr}
1>16 | a
1>20 | b
1> +---
1>DerivedClass1::$vftable@DerivedClass1@:
1> | &DerivedClass1_meta
1> | 0
1> 0 | &DerivedClass1::Derivedcommonfunction1
1>DerivedClass1::$vbtable@:
1> 0 | -4
1> 1 | 8 (DerivedClass1d(DerivedClass1+4)Base)
1>DerivedClass1::$vftable@Base@:
1> | -12
1> 0 | &Base::VirtualFunction
1>DerivedClass1::Derivedcommonfunction1 this adjustor: 0
1>vbi: class offset o.vbptr o.vbte fVtorDisp
1> Base 12 4 4 0
1>class DerivedClass2 size(16):
1> +---
1> 0 | +--- (base class Base)
1> 0 | | {vfptr}
1> 4 | | a
1> 8 | | b
1> | +---
1>12 | c
1> +---
1>DerivedClass2::$vftable@:
1> | &DerivedClass2_meta
1> | 0
1> 0 | &Base::VirtualFunction
1> 1 | &DerivedClass2::Derivedcommonfunction1
1>DerivedClass2::Derivedcommonfunction1 this adjustor: 0
1>class DerivedClass3 size(44):
1> +---
1> 0 | +--- (base class DerivedClass1)
1> 0 | | {vfptr}
1> 4 | | {vbptr}
1> 8 | | c
1> | +---
1>12 | +--- (base class DerivedClass2)
1>12 | | +--- (base class Base)
1>12 | | | {vfptr}
1>16 | | | a
1>20 | | | b
1> | | +---
1>24 | | c
1> | +---
1>28 | c
1> +---
1> +--- (virtual base Base)
1>32 | {vfptr}
1>36 | a
1>40 | b
1> +---
1>DerivedClass3::$vftable@DerivedClass1@:
1> | &DerivedClass3_meta
1> | 0
1> 0 | &DerivedClass3::Derivedcommonfunction1
1>DerivedClass3::$vftable@:
1> | -12
1> 0 | &Base::VirtualFunction
1> 1 | &thunk: this-=12; goto DerivedClass3::Derivedcommonfunction1
1>DerivedClass3::$vbtable@:
1> 0 | -4
1> 1 | 28 (DerivedClass3d(DerivedClass1+4)Base)
1>DerivedClass3::$vftable@Base@:
1> | -32
1> 0 | &Base::VirtualFunction
1>DerivedClass3::Derivedcommonfunction1 this adjustor: 0
1>vbi: class offset o.vbptr o.vbte fVtorDisp
1> Base 32 4 4 0