3.4 C++四种继承关系中内存分布

原创 2016年08月31日 16:55:51

1、单一继承不含虚函数

在这种情况下,对象会保持基类的原样性,并且一个class derived class object表现出来的东西,是其自己的members加上其base classes members的总和。

class Point2d
{
	int a;
	char b;
};

class Point3d : public Point2d
{
	char c;
};
对于上述类,其模型如下:

                      

2、单一继承含虚函数

与单一继承不含虚函数唯一不同的是,在含有虚函数时,vptr放置的位置。如果vptr放置在起始位置处,则会表现出非自然多态。如果在在尾处,则可以自然多态。下面是一个构造的具有虚函数的继承类。

class Point2d
{
	int a;
	char b;
};

class Point3d : public Point2d
{
	char c;
public:
	virtual void print()
	{
		std::cout << "this is the Point2d" << std::endl;
	}
};
class Point4d : public Point3d
{
	char d;
public:
	void print() override
	{
		std::cout << "this is the Point4d" << std::endl;
	}
};

   对于上述类,其模型如下:

3、多重继承

多重继承的问题主要发生于derived class objects和其第二或后继的base class之间的转换。他的内存分布其实各个部分相加再加上自己的部分。

class Point3d
{
private:
	int _x, _y,_z;
public:
	virtual void print()
	{
		std::cout << "this is the point3d" << std::endl;
	}

};

class Vertex
{
private:
	char v;
public:
	virtual void print()
	{
		std::cout << "this is the vertex" << std::endl;
	}
};

class Vertex3d : public Point3d, public Vertex
{
	int num;
};
对于这个类,它们的模型是:


在这个模型中,类型转换是如何发生的呢?

Point3d* ptrP3d1;
	Vertex* ptrVtx1;
	Vertex3d* ptrVtx3d1;
	Vertex3d vtx3d1;
	ptrP3d1 = &vtx3d1;//自然多态,不需要编译器参与
	ptrVtx1 = &vtx3d1;//非自然多态,需要编译器参数 ptrVtx1 = (Vertex*)((char*)(&vtx3d1)+sizeof(Point3d));
	ptrVtx3d1 = &vtx3d1;
	ptrVtx1 = ptrVtx3d1;//非自然多态,需要编译器 ptrVtx1 =ptrVtx3d1?(Vertex*)((char*)(ptrVtx3d1)+sizeof(Point3d)):0
4、虚拟继承

Class如果内含一个或多个virtual base class subobjects,将被分割成两部分:一个不变区域和一个共享区域。共享区域指的是virtual base class subobject这一部分,其位置会因为每次的派生操作而有变化。

下面我将分析一组虚拟派生继承,以及它在vs中的内存分布。代码如下:

class Point
{
	char p;
};

class Point2d : public virtual Point
{
	int a;
	int aa;
	char aaa;
};

class Point3d : public virtual Point2d
{
	int b;
public:
	virtual void print()
	{
		std::cout << "this is the Point3d" << std::endl;
	}
};

class Vertex : public virtual Point2d
{
	int c;
	
public:
	virtual void print()
	{
		std::cout << "this is the Vertex" << std::endl;
	}
};

class Vertex3d : public Point3d, public Vertex
{
	int d;
};

在这段代码中,其所构造的模型如下:

这是我根据在vs2015中根据类大小进行判断的,这个模型最大的坏处是:随着虚拟继承链的加长,导致间接存取层次的增加。

C++类内存分布+钻石模型的解决方法

C++类内存分布#include using namespace std; class Base { private: int val; public: ...
  • huai1693838234
  • huai1693838234
  • 2015年03月23日 15:47
  • 932

C++对象内存分布(包括字节对齐和虚函数表)

1、C++对象的内存分布和虚函数表:     http://blog.sina.com.cn/s/blog_60e96a410100lirk.html,注意,对象中保存的是虚函数表指针,而不是虚函数表...
  • zhaopengnju
  • zhaopengnju
  • 2016年06月02日 22:32
  • 657

C++类内存分布

http://www.cnblogs.com/jerry19880126/p/3616999.html C++类内存分布 书上类继承相关章节到这里就结束了,这里...
  • wangyin159
  • wangyin159
  • 2015年06月28日 09:19
  • 434

C++对象的内存分布和虚函数表

c++中一个类中无非有四种成员:静态数据成员和非静态数据成员,静态函数和非静态函数。    1.非静态数据成员被放在每一个对象体内作为对象专有的数据成员。    2.静态数据成员被提取出来放在程序的静...
  • maomao171314
  • maomao171314
  • 2014年12月12日 14:55
  • 638

C/C++进程内存的分布

内存分布只要分为五部分: text(文本段),initialize data(数据段),uninitialized data(为初始化数据段),heap(堆),stack(栈), 如下图: ...
  • qq_26685951
  • qq_26685951
  • 2017年08月08日 17:16
  • 90

C/C++ 程序进程在内存中的分布

c/c++程序进程在内存中的表示包括: 文本段 初始化数据段 未初始化数据段 堆 栈文本段, 也称作代码段。 主要包含可执行代码,这部分是只读的。 初始化数据段,也通常简称为数据段。它包含全局变量和由...
  • wangbingcsu
  • wangbingcsu
  • 2015年09月07日 16:17
  • 465

C++对象模型之简述C++对象的内存布局

在C++中,有两种类的成员变量:static和非static,有三种成员函数:static、非static和virtual。那么,它们如何影响C++的对象在内存中的分布呢? 当存在继承的情况下,其内存...
  • ljianhui
  • ljianhui
  • 2015年05月22日 02:28
  • 9747

[c/c++]class/struct数据在内存中的布局

请看下面两段代码 看似一样 但是得到的结果却不同 struct test1 { int a; bool d; int32_t b; bool e; float ...
  • kuai0705
  • kuai0705
  • 2014年03月09日 14:20
  • 1662

C++语言--数组-6.1----数组在内存中的分布、数组名和函数、枚举常量

前言:2017年第一篇博客,祝大家新年快乐!! 1.数组在内存中的分布 我们来分析为什么a[0]=3?在C++中我们知道数组b中的最大下标角为9,当我们赋值给b[10]时,即使在数组b中下标1...
  • wu371894545
  • wu371894545
  • 2017年02月05日 15:42
  • 270

全面介绍Windows内存管理机制及C++内存分配实例

转自:http://blog.csdn.net/yeming81/article/details/2046193 本文基本上是windows via c/c++上的内容,笔记做得不错。。 本文背景...
  • vsooda
  • vsooda
  • 2013年05月30日 09:44
  • 21562
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:3.4 C++四种继承关系中内存分布
举报原因:
原因补充:

(最多只允许输入30个字)