c++中的单继承,多继承(此处着重讲菱形继承)的内存布局模型详解
2016-10-29 20:13
344 查看
最近正好复习到继承的相关部分,想着把自己所学的东西还是再次归纳整理一遍,那么接下来就简单地梳理一下关于继承的一些知识点。
切入正题,什么是继承?“继承是c++语言的一种重要机制,该机制自动地为一个类提供来自另一个类的操作和数据结构,使得程序员只需在新类中定义已有类中没有的成分来建立新类”对没错这是书本的官方解释,相信你看了之后还是和我一样一脸懵逼没有任何感觉(就不能解释的通俗一点嘛,卖萌脸)。下面直接上图,清晰明了:
以我们手机的更新换代为例,每次新手机的发布都会在原来的基础上增加新功能(即它保留了原来的东西,而又新加入了自己特有的新元素),如此图中的4s和5s,它们的好多功能是重复的,那么为了减少这种重复,我们就可以使用继承,这里,可以说5s继承于4s。
说完了继承的概念,接下来简单的相关内容看看书就不难理解,本文我们主要来看一下继承当中成员分布的对象模型(即它们在内存当中具体是怎么分配的)。
首先来看下面一段代码:
而如果将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类的内存布局如图所示:
下来我们调出窗口验证一下
可知,猜想是完全正确的。
切入正题,什么是继承?“继承是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类的内存布局如图所示:
下来我们调出窗口验证一下
可知,猜想是完全正确的。
相关文章推荐
- C++继承详解之三——菱形继承+虚继承内存对象模型详解vbptr(1)
- 三十二、C++内存布局,对象大小计算、虚函数虚继承对类内存模型的影响
- 【C++】菱形虚拟继承(内存布局)
- 虚继承内存布局@c++对象模型
- C++继承模型的内存布局
- 【转】图说C++对象模型:对象内存布局详解
- 图说C++对象模型:对象内存布局详解
- c++单继承、多继承、菱形继承内存布局(虚函数表结构)
- 关于C++对象继承中的内存布局示例详解
- 图说C++对象模型:对象内存布局详解
- C++对象内存布局--⑩GCC编译器--虚拟继承--菱形继承
- 图说C++对象模型:对象内存布局详解
- ★★★★★图说C++对象模型:对象内存布局详解
- 【C++】c++单继承、多继承、菱形继承内存布局(虚函数表结构)
- 图说C++对象模型:对象内存布局详解
- C++对象模型之内存布局三(虚继承)
- C++对象内存布局--⑨VS编译器--虚拟继承--菱形继承
- 图说C++对象模型:对象内存布局详解
- c++单继承、多继承、菱形继承的内存布局(虚函数表结构)
- C++继承(单继承、多继承、菱形继承)内存模型的深入研究