首先为cpp文件添加额外的命令行选项 /d1 reportAllClassLayout
下面对几种情况分别讨论
单一简单类
class father
{
public:
father(){};
~father(){};
public:
void doSomething(){};
static void sDoSomething(){};
private:
char a;
int b;
static int c;
};
对他进行编译,我们可以在控制台看到
1> class father size(8):
1> + - - -
1> 0 | a
1> | < alignment member >(size=3)
1> 4 | b
1> + - - -
开头的0,4为类内偏移。我们可以看到静态变量、函数和静态函数都不占类实例对象的内存空间。且中间有一段空白区域因内存对齐而空出来。
带有虚函数的单一类
将上面的代码简化并添加虚函数
class father
{
public:
father(){};
virtual ~father(){};
private:
char a;
int b;
public:
virtual void doSomething(){};
};
编译结果如下
1> class father size(12):
1> + - - -
1> 0 | {vfptr}
1> 4 | a
1> | < alignment member > (size=3)
1> 8 | b
1> + - - -
1>
1> father::$vftable@:
1> | &father_meta
1> | 0
1> 0 | &father::{dtor}
1> 1 | &father::doSomething
我们可以看到跟没有虚函数相比,类的开头多了一个{vfptr},这个就是虚函数表指针,在32位下占用4字节。
继续往下看,在&father_meta下方的0表示这个虚函数表指针在类内的偏移,不过在vs2013中查看内存并没有在虚函数表的开头看到这个偏移量所占的内存。
虚函数表的开头数字则只是表示序号而不是偏移。
无虚函数的多继承
class father
{
private:
char a;
int b;
public:
void doSomething(){};
};
class mother
{
private:
char a;
int b;
public:
void doSomething(){};
};
class son :public father,public mother
{
public:
char a;
int b;
public:
void doSomething(){};
};
编译结果如下,只把son类结构贴出来
1> class son size(24):
1> + - - -
1> | + - - - (base class father)
1> 0 | | a
1> | | < alignment member > (size=3)
1> 4 | | b
1> | + - - -
1> | + - - - (base class mother)
1> 8 | | a
1> | | < alignment member > (size=3)
1> 12 | | b
1> | + - - -
1> 16 | a
1> | < alignment member > (size=3)
1> 20 | b
1> + - - -
通过观察发现无虚函数的正常继承,在内存中按继承的从左往右顺序连续排列,最后才是派生类。
有虚函数的多继承
class father
{
private:
char a;
int b;
public:
virtual void doSomething(){};
};
class mother
{
private:
char a;
int b;
public:
virtual void doSomething(){};
};
class son :public father,public mother
{
private:
char a;
int b;
public:
virtual void doSomething(){};
virtual void sonDoHimself(){};
};
编译结果如下
1> class son size(32):
1> +---
1> | +--- (base class father)
1> 0 | | {
vfptr}
1> 4 | | a
1> | | <alignment member> (size=3)
1> 8 | | b
1> | +---
1> | +--- (base class mother)
1> 12 | | {
vfptr}
1> 16 | | a
1> | | <alignment member> (