C语言中类被继承的过程中,你知道内存

白癜风检查到中科 https://jbk.39.net/yiyuanfengcai/video_bjzkbdfyy/

之前一节成为高手必须弄懂的问题,C++语言中类在内存中是如何存储的?讨论了C++语言中类在内存中分布模型,提到了C++语言编译器会自动为每一个拥有虚函数的类创建虚表和虚表指针,其中虚表指针指向虚表,而虚表则用于存放虚函数指针,如下图所示:

C++虚函数的内存分布

基类的内存模型

那么,若是拥有虚函数的类A作为基类,派生出其他类,这些派生类如何处理类A的虚表呢?换句话说,C++语言中的派生类是如何继承基类的虚函数的呢?为了便于讨论,先将类A的C++语言代码补充完整,请看:

类A的C++语言代码

在上述C++语言代码中,类A拥有两个常规函数,两个int型变量,此外它还有两个虚函数vfoo1()和vfoo2(),因此编译器处理类A时,会自动为它分配一个虚表,用于存放vfoo1()和vfoo2()两个函数的地址。我们先定义一个A对象,并将相关成员的地址打印出来,相关的C++语言代码如下,请看:

Aa;

print_addr(A,a);

因为稍后还要分析基类A的派生类成员地址,所以为了方便,将打印地址的功能定义为

print_addr()宏了,它的C++语言代码如下,请看:

print_addr()宏的代码

编译并执行,得到如下输出:

输出

在C++语言类的内存分布一节我们曾提到类的成员函数是独立存储的,只有成员变量和虚表指针(如果该类有虚函数的话)才会为类占据内存空间,因此对象a的size为24,正是它的3个int型的成员变量与一个虚表指针占用的内存大小。

在我的机器上,int型变量占用内存为4字节,指针占用内存大小为8字节。到这里可能有读者迷惑了,3个int型成员变量占用的内存为12字节,加上虚表指针的8字节,也才20字节,而sizeof(a)等于24,多出的4字节从哪里来呢?请参考我之前关于内存对齐的文章。

内存对齐后,对象a的内存分布如下图所示:

对象a的内存分布

派生类的内存模型

类A作为基类,肯定可以被其他派生类继承的,下面是一段C++语言代码示例:

C++语言代码示例

上述C++语言代码定义了继承基类A的派生类B,接着又以类B为基类定义了派生类C。其中类B重写了由基类A继承而来的虚函数vfoo1(),类C重写了由基类B继承而来的虚函数vfoo2()。为了弄清派生类的内存模型,我们使用

print_addr()

宏将类A、B、C相关的地址打印出来:

Aa;

Bb;

Cc;

coutendl;

print_addr(A,a);

coutendl;

print_addr(B,b);

coutendl;

print_addr(C,c);

coutendl;

编译并执行这段C++语言代码,得到的输出如下:

输出




转载请注明:http://www.aierlanlan.com/rzfs/3383.html