设为首页 加入收藏

TOP

怎么计算C++继承、虚继承、虚函数类的大小?(二)
2018-03-09 09:08:01 】 浏览:358
Tags:怎么 计算 继承 函数 大小
o的指针,如果这时候创建一个CVirtualNull对象,会发现它的虚表的内容跟这个一样

评注:由于父类带了虚函数,子类就算没有显式声明虚函数,虚表还是存在的,虚表存放的位置跟父类不同,但内容是同的,也就是对父类虚表的复制。

十三、子类有新的虚函数

C++代码

classCVirtualDerived:publicCVirtualNull

{

public:

CVirtualDerived(){m_iVD=0xFF;};

~CVirtualDerived(){};

virtualvoidFoo2(){printf("Foo2/n");};

private:

intm_iVD;

};

长度:8

内存结构:

24 61 42 00 //虚表指针

FF 00 00 00 //m_iVD

00426124:(虚表)

23 10 40 00

50 10 40 00

评注:虚表还是只有一张,不会因为增加了新的虚函数而多出另一张来,新的虚函数的指针将添加在复制了的虚表的后面。

十四、当纯虚函数(pure function)出现时

C++代码

classCPureVirtual

{

virtualvoidFoo()=0;

};

classCDerivePV:publicCPureVirtual

{

voidFoo(){printf("vd:Foo/n");};

};

长度:4(CPureVirtual),4(CDerivePV)

内存结构:

CPureVirtual:

(不可实例化)

CDerivePV:

28 50 42 00 //虚表指针

00425028:(虚表)

5A 10 40 00 //指向Foo的函数指针

评注:带纯虚函数的类不可实例化,因此列不出其“内存结构”,由其派生类实现纯虚函数。我们可以看到CDerivePV虽然没有virtual声明,但由于其父类带virtual,所以还是继承了虚表,如果CDerivePV有子类,还是这个道理。

十五、虚函数类的多重继承

前面提到:(子类的虚表)不会因为增加了新的虚函数而多出另一张来,但如果有多重继承的话情况就不是这样了。下例中你将看到两张虚表。

怎样计算C++继承、虚继承、虚函数类的大小

大小:24

内存结构

F8 50 42 00 //虚表指针

01 00 00 00 //m_iA

02 00 00 00 //m_iB

E8 50 42 00 //虚表指针

03 00 00 00 //m_iC

04 00 00 00 //m_iComplex

004250F8:(虚表)

5A 10 40 00 //FooA

55 10 40 00 //FooB

64 10 40 00 //FooComplex

004250E8:(虚表)

5F 10 40 00 //FooC

评注:子类的虚函数接在第一个基类的虚函数表的后面,所以B接在A后面,Complex接在B后面。基类依次出现,子类成员接在最后面,所以m_iComplex位于最后面。

十六、包含虚函数类的虚继承

C++代码

classVirtualInheritance

{

chark[3];

public:

virtualvoidaa(){};

};

classsonClass1:publicvirtualVirtualInheritance

{

charj[3];

public:

virtualvoidbb(){};

};

classsonClass2:publicvirtualsonClass1

{

charf[3];

public:

virtualvoidcc(){};

};

intmain()

{

cout

return0;

}

输出的结果:

visio studio: 8,20,32

gcc: 8,16,24

评注:

对于VirtualInheritance类,大小为8, 没有异议,他有个虚表指针vtp_VirtualInheritanc;

对于sonClass1类:

在visio studio 编译器下,大小为20。由于是虚拟继承,又有自己的虚函数,所以先拥有一个自己的虚函数指针vpt_sonClass1,大小为4,指向自己的虚表;还要有一个char[3],大小为4;为了实现虚拟继承,首先sonClass1加入了一个指向其父类的虚类指针,记作vtp_sonClass1_VirtualInheritanc,大小为4;然后在加上父类的所有大小8,所以总共是20字节。

在gcc编译器下,大小为16,没有计算子类中指向父类的虚类指针vtp_sonClass1_VirtualInheritanc的大小。

对于sonClass2:

在visio studio环境下,大小为32。和上面一样,子类拥有char[3],大小为4字节,因为是虚继承,还有自己的虚函数,所以拥有自己的一个虚表指针,vtp_sonClass2,大小为4字节。然后还有一个指向父类的虚类指针vtp_sonClass2_sonClass

1,大小为4。最后加上其父类的总大小20,所以总的大小为4+4+4+20=32;

在gcc环境下,没有计算虚类指针的大小,即4+4+16=24。

17、包含虚函数的多重普通、虚拟混合继承

C++代码

classVirtualInheritance

{

chark[3];

public:

virtualvoidaa(){};

};

classsonClass1:publicvirtualVirtualInheritance

{

charj[3];

public:

virtualvoidbb(){};

};

classVirtualInheritance2

{

charl[3];

public:

virtualvoiddd(){};

};

classsonClass2:publicvirtualsonClass1,publicVirtualInheritance2

{

charf[3];

public:

virtualvoidcc(){};

};

intmain()

{

cout

return0;

}

评注:此时sonClass2的大小变成36。和16不同的是,此时sonClass2是多重继承,其中一个是虚继承,一个普通继承,他的大小在visio studio中变成36,相比16增加了4,这刚好是char l[3]的大小,因为耸sonClass2已经有了一个虚表,所以在他原有的虚表中多一条记录即可。

18、包含虚函数的多重虚拟继承

C++代码

classVirtualInheritance

{

chark[3];

public:

virtualvoidaa(){};

};

classsonClass1:publicvirtualVirtualInheritance

{

charj[3];

public:

virtualvoidbb(){};

};

classVirtualInheritance2

{

charl[3];

public:

virtualvoiddd(){};

};

classsonClass2:publicvirtualsonClass1,publicvirtualVirtualInheritance2

{

charf[3];

public:

virtualvoidcc(){};

};

intmain()

{

cout

return0;

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++ 中友元函数的使用介绍 下一篇C++ 旧式转型、类型转型方法

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目