C++ 虚函数占用大小

       根据原始定义,知道:一旦存在虚函数,类中将存在虚函数表,变量中会多一个虚函数表的指针,从而在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变量(82字节),占用两个字节,同时由于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)
       证明2:sizeof(ClassParent2) == sizeof(ClassChild2)
       3.继承自多个虚类的话,并存多个虚函数指针
       证明:sizeof(ChildBoth) = 40
       分析,分别从基类ClassParent1继承过来一个虚函数指针,又从ClassParent2继承过来一个虚函数指针,所以ChildBoth存有两个虚函数指针。ChildBoth实例化ClassParent1的虚函数FuncA(),则会修改继承自ClassParent1的虚函数表;实例化ClassParent2的虚函数FuncB(),则会修改继承自ClassParent2的虚函数表。
       猜测:ChildBoth本身添加的虚函数FuncE()存储在继承自第一个基类虚函数指针指向的虚函数表中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#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(){};
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
int nSizeParent1 = sizeof(ClassParent1);
int nSizeParent2 = sizeof(ClassParent2);
cout<<"Parent1="<<nSizeParent1<<";
cout<<"Parent2="<<nSizeParent2<<endl;
int nSizeChild1 = sizeof(ClassChild1);
int nSizeChild2 = sizeof(ClassChild2);
int nSizeChildBoth = sizeof(ClassChildBoth);
cout<<"Child1="<<nSizeChild1<<"Child2="<<nSizeChild2;
cout<<"ChildBoth="<<nSizeChildBoth<<endl;
getchar();
return 0;
}

       执行结果:

1
2
3
4
5
6
Parent1=24;
Parent2=16;
Child1=24;
Child2=16;
ChildBoth=40;
ChildBoth=40;

文章目录