设为首页 加入收藏

TOP

怎么计算C++继承、虚继承、虚函数类的大小?(一)
2018-03-09 09:08:01 】 浏览:355
Tags:怎么 计算 继承 函数 大小

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

一、真空类

C++代码

classCNull

{

};

长度:1

内存结构:

评注:长度其实为0,这个字节作为内容没有意义,可能每次都不一样。

二、空类

C++代码

classCNull2

{

public:

CNull2(){printf("Construct/n");}

~CNull2(){printf("Desctruct/n");}

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

};

长度:1

内存结构:

评注:同真空类差不多,内部的成员函数并不会影响类大小。

三、简单类

C++代码

classCOneMember

{

public:

COneMember(intiValue=0){m_iOne=iValue;};

private:

intm_iOne;

};

长度:4

内存结构:

00 00 00 00 //m_iOne

评注:成员数据才影响类大小。

四、简单继承

C++代码

classCTwoMember:publicCOneMember

{

private:

intm_iTwo;

};

长度:8

内存结构:

00 00 00 00 //m_iOne

CC CC CC CC //m_iTwo

评注:子类成员接在父类成员之后。

五、再继承

C++代码

classCThreemember:publicCTwoMember

{

public:

CThreemember(intiValue=10){m_iThree=iValue;};

private:

intm_iThree;

};

长度:12

内存结构:

00 00 00 00 //m_iOne

CC CC CC CC //m_iTwo

0A 00 00 00 //m_iThree

评注:孙类成员接在子类之后,再再继承就依此类推了。

六、多重继承

C++代码

classClassA

{

public:

ClassA(intiValue=1){m_iA=iValue;};

private:

intm_iA;

};

classClassB

{

public:

ClassB(intiValue=2){m_iB=iValue;};

private:

intm_iB;

};

classClassC

{

public:

ClassC(intiValue=3){m_iC=iValue;};

private:

intm_iC;

};

classCComplex:publicClassA,publicClassB,publicClassC

{

public:

CComplex(intiValue=4){m_iComplex=iValue;};

private:

intm_iComplex;

};

长度:16

内存结构:

01 00 00 00 //A

02 00 00 00 //B

03 00 00 00 //C

04 00 00 00 //Complex

评注:也是父类成员先出现在前边,我想这都足够好理解。

七、复杂一些的继承

不写代码了,怕读者看了眼花,改画图。

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

长度:32

内存结构:

01 00 00 00 //A

02 00 00 00 //B

03 00 00 00 //C

04 00 00 00 //Complex

00 00 00 00 //OneMember

CC CC CC CC //TwoMember

0A 00 00 00 //ThreeMember

05 00 00 00 //VeryComplex

评注:还是把自己的成员放在最后。

只要没涉及到“虚”(Virtual),我想没什么难点,不巧的是“虚”正是我们要研究的内容。

八、趁热打铁,看“虚继承”

C++代码

classCTwoMember:virtualpublicCOneMember

{

private:

intm_iTwo;

};

长度:12

内存结构:

E8 2F 42 00 //指针,指向一个关于偏移量的数组,且称之虚基类偏移量表指针

CC CC CC CC // m_iTwo

00 00 00 00 // m_iOne(虚基类数据成员)

评注:virtual让长度增加了4,其实是多了一个指针,关于这个指针,确实有些复杂,别的文章有具体分析,这里就不岔开具体讲了,可认为它指向一个关于虚基类偏移量的数组,偏移量是关于虚基类数据成员的偏移量。

九、“闭合”虚继承,看看效果

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

长度:24

内存结构:

14 30 42 00 //ClassB的虚基类偏移量表指针

02 00 00 00 //m_iB

C4 2F 42 00 //ClassC的虚基类偏移量表指针

03 00 00 00 //m_iC

04 00 00 00 //m_iComplex

01 00 00 00 //m_iA

评注:和预料中的一样,虚基类的成员m_iA只出现了一次,而且是在最后边。当然了,更复杂的情况要比这个难分析得多,但虚继承不是我们研究的重点,我们只需要知道:虚继承利用一个“虚基类偏移量表指针”来使得虚基类即使被重复继承也只会出现一次。

十、看一下关于static成员

C++代码

classCStaticNull

{

public:

CStaticNull(){printf("Construct/n");}

~CStaticNull(){printf("Desctruct/n");}

staticvoidFoo(){printf("Foo/n");}

staticintm_iValue;

};

长度:1

内存结构:(同CNull2)

评注:可见static成员不会占用类的大小,static成员的存在区域为静态区,可认为它们是“全局”的,只是不提供全局的访问而已,这跟C的static其实没什么区别。

十一、带一个虚函数的空类

C++代码

classCVirtualNull

{

public:

CVirtualNull(){printf("Construct/n");}

~CVirtualNull(){printf("Desctruct/n");}

virtualvoidFoo(){printf("Foo/n");}

};

长度:4

内存结构:

00 31 42 00 //指向虚函数表的指针(虚函数表后面简称“虚表”)

00423100:(虚表)

41 10 40 00 //指向虚函数Foo的指针

00401041:

E9 78 02 00 00 E9 C3 03 … //函数Foo的内容(看不懂)

评注:带虚函数的类长度就增加了4,这个4其实就是个指针,指向虚函数表的指针,上面这个例子中虚表只有一个函数指针,值就是“0x00401041”,指向的这个地址就是函数的入口了。

十二、继承带虚函数的类

C++代码

classCVirtualDerived:publicCVirtualNull

{

public:

CVirtualDerived(){m_iVD=0xFF;};

~CVirtualDerived(){};

private:

intm_iVD;

};

长度:8

内存结构:

3C 50 42 00 //虚表指针

FF 00 00 00 //m_iVD

0042503C:(虚表)

23 10 40 00 //指向虚函数Fo

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

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目