c++-对象模型

1.C++对象模型
nonstatic data members被配置于每一个class object内.
static data members被存储在class object外.
staticnonstatic function members实现代码也存储在class object外.
virtual functions:
a. 每个class产生一堆指向virtual functions指针,放在表格中.表中每个条目指向该类型的一个虚函数代码实例的起始地址.
b. 每个class object被安插一个指针,执行相关的virtual tablevptr的设定,重置由每一个classconstructor/destructor/copy assignment自动完成.每一个class所关联的type_info object也放在表格中.
c. 一个class object所需内存构成,一般要有:
c.1. 其nonstatic data members的总和大小
c.2. 加上由alignment的需求而填补上去的空间
c.3. 加上为支持virtual而产生的负担

2.注意点
对一个包含虚表指针的类对象执行memset(&obj, 0, sizeof(obj))存在把保存在类对象内的虚表指针设为0的风险.

3.虚拟继承下的类型尺寸

class X {
};
class V1{
	int i2;
	virtual void fun(){}
};
class V2:public virtual V1{
	int i;
	virtual void fun2(){}
};
class V3:public V2,public virtual V1
{
public:
	int i;
	virtual void fun3(){}
};

类型尺寸:
a. sizeof(X)1
b. sizeof(V1)16
c. sizeof(V2)32
d. sizeof(V3)32
C++中,当使用虚继承时,类的内存布局会发生变化,主要是为了处理多重继承时的公共基类子对象问题。虚继承通过在继承体系中引入一个共享的、指向公共基类子对象的指针(通常称为虚基类指针或vptr),来确保只有一个公共基类的实例存在于派生类中。
针对上述:
(1). class X {}: X 是一个空类,但即使如此,编译器通常也会为它分配至少一个字节的内存,以区分不同的对象。这是为了确保两个不同类型的空对象在内存中占据不同的地址。若空类作为基类时,其尺寸计算为0.因为此时派生类非空类时,类型实例至少有1个字节内存.无需上述处理.派生类也是空类时,派生类实例整体占1字节即可.
(2). 虚拟继承
上述虚拟继承下V1,V2,V3实例对象可能的内存布局:
在这里插入图片描述
上述是V1
在这里插入图片描述
上述是V2
在这里插入图片描述
上述是V3

4.C++如何实现多态
对含虚函数的class有且仅有一个virtual table,每个table内含其对应之class object中所有active virtual functions函数实例的地址.
active virtual functions包括:
(1). class自身新定义或重载的虚函数.
(2). 继承自base class的虚函数.

一个实际例子

class point{
public:
	virtual ~point(){}
	virtual void mult() = 0;
	virtual void y()[}
	virtual void z(){}
private:
	int x;
};

x实例对象内存可能的布局示意图:
在这里插入图片描述

指向的虚表可能的构成示意:
在这里插入图片描述

class point2d : public point
{
public:
	virtual ~point2d(){}
	virtual void y(){}
	virtual void mult(){}
public:
	int y;
};

一个point2d实例可能的内存布局示意:
在这里插入图片描述

point2d可能的虚表构成:
在这里插入图片描述
在上述背景下,通过基类point指针ptry()时:
(1). 依据实例对象起始地址,容易定位到对象内虚表指针.
(2). 通过函数名易于定位到需表中表项位置.
这样就完成了多态调用.

5.多重继承下多态的一个可能实现说明

struct Base1{
public:
	int a;
	virtual ~Base1(){}
	virtual SpeakClearly(){}
};

在这里插入图片描述

struct Base2{
public:
		int b;
		virtual ~Base2(){}
		virtual void mumble(){}
		virtual void clone(){}
};

内存布局略.

struct  Derived : public Base1, public Base2{
public:
	int c;
	virtual ~Derived(){}
	virtual void clone(){}
};

在这里插入图片描述
这里一个Derived实例对象将含两个虚表指针.(单独继承下只有一个).且每个Base1部分的虚表指针,Base2部分的虚表指针所指向的虚表.由基类虚函数,派生类重载综合得到.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值