c++中的单继承,多继承(此处着重讲菱形继承)的内存布局模型详解

来源:互联网 发布:柴庆丰事件知乎 编辑:程序博客网 时间:2024/06/07 00:02

最近正好复习到继承的相关部分,想着把自己所学的东西还是再次归纳整理一遍,那么接下来就简单地梳理一下关于继承的一些知识点。

切入正题,什么是继承?继承是c++语言的一种重要机制,该机制自动地为一个类提供来自另一个类的操作和数据结构,使得程序员只需在新类中定义已有类中没有的成分来建立新类对没错这是书本的官方解释,相信你看了之后还是和我一样一脸懵逼没有任何感觉(就不能解释的通俗一点嘛,卖萌脸)。下面直接上图,清晰明了:


以我们手机的更新换代为例,每次新手机的发布都会在原来的基础上增加新功能(即它保留了原来的东西,而又新加入了自己特有的新元素),如此图中的4s和5s,它们的好多功能是重复的,那么为了减少这种重复,我们就可以使用继承,这里,可以说5s继承于4s。

说完了继承的概念,接下来简单的相关内容看看书就不难理解,本文我们主要来看一下继承当中成员分布的对象模型(即它们在内存当中具体是怎么分配的)。

首先来看下面一段代码:

#include<iostream>using namespace std;#include<stdlib.h>class B{public:int _a;int _b;int _c;int _d;};void fun(){B b;b._a = 1;b._b = 2;b._c = 3;b._d = 4;}int main(){fun();cout << sizeof(B) << endl;system("pause");return 0;}
运行结果及内存布局如下


而如果将public中成员_a与_b的顺序调换一下,即变为int _b;int _a;int _c;int _d.则内存布局变为


由此,我们可以得出类中成员的分布和其在类中出现的先后次序有关。

而我们知道继承又分为两种:单继承与多继承。而它们在内存中的布局又是怎样的呢?

下面是一个单继承的例子


#include<iostream>using namespace std;class B{public:int _b;};class C:public B{public:int _c;};void fun(){B b;C c;}int main(){fun();return 0;}
在此段代码中,C类公有继承自B类,那么C类对象的内存布局到底是怎样的,接下来我们调出监视看一下C类对象的内存布局(为了方便看出,在第二张图中我们分别对_b与_c赋值为1,2)结果如下:


可以看出,布局依次为先是基类中的对象成员_b,然后 再是C类对象自己的成员_c,总结如下图:



再来看多继承:


代码如下:

<pre name="code" class="cpp">#include<iostream>using namespace std;#include<stdlib.h>class B1{public:int _b1;};class B2{public:int _b2;};class C:public B1,public B2{public:int _c;};void fun(){C c;cout << sizeof(C) << endl;}int main(){fun();system("pause");return 0;}


同样,为了方便看具体内存布局,我们给各个类的成员进行了赋值,运行结果即监视如下:


可以看到C类的大小为12个字节,布局为先基类B1的成员_b1,再是基类B2的成员_b2,最后才是自己的成员_c,总结如下图所示:



最后我们来看多继承中一种较为复杂的继承---->菱形继承:


代码如下:

#include<iostream>using namespace std;#include<stdlib.h>class B{public:int _b;};class C1:public B{public:int _c1;};class C2 :public B{public:int _c2;};class D :public C1, public C2{public:int _d;};void fun(){cout << sizeof(B) << endl;cout << sizeof(C1) << endl;cout << sizeof(C2) << endl;cout << sizeof(D) << endl;D d;d.C1::_b = 1;d._c1 = 2; d.C2::_b = 3;d._c2 = 4;d._d = 5;}int main(){fun();system("pause");return 0;}

运行结果如图所示,C类的大小为20个字节,结合前边所讲的内容,不难才想出D类的内存布局如图所示:





下来我们调出窗口验证一下

可知,猜想是完全正确的。







1 0
原创粉丝点击