您的位置:首页 > 编程语言 > C语言/C++

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

2016-10-29 20:13 344 查看
最近正好复习到继承的相关部分,想着把自己所学的东西还是再次归纳整理一遍,那么接下来就简单地梳理一下关于继承的一些知识点。
切入正题,什么是继承?“继承是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类的内存布局如图所示:





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



可知,猜想是完全正确的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: