C++对象内存模型

一、虚函数表指针和虚函数表

  1. 虚函数表指针个数与派生类继承父类个数有关,多一个父类,派生类就多一个虚函数表指针和虚函数表;
  2. 虚函数表是编译器为每个拥有虚函数的类创建的一个全局资源,它不属于类也不属于类对象,但它服务于类及其对象。
  3. 虚函数指针(vptr)是每个类对象的一部分,随着对象的创建而存在,并指向对应的虚函数表。
  4. 派生类和父类同时含有虚函数时,派生类的虚函数按照父类声明的顺序(从左到右),存放在第一个父类的虚函数表后面;
  5. 成员变量按照先声明、先存储、先父类、再子类的顺序存放;
  6. 无论是派生类还是父类,当出现虚函数(普通虚函数、纯虚函数、虚虚构函数),虚函数表指针放在内存的最前面;

二、覆盖和继承

  1. 派生类和父类出现同名成员变量时,派生类仅仅时将父类的同名承运隐藏了,而非覆盖替换;
  2. 派生类调用成员变量时,按就近原则,调用自身的同名变量,避免了调用变量时的二义性;
  3. 派生类出现和父类同名的虚函数时,派生类的虚函数表中将子类同名的函数地址替换为自身的同名虚函数地址,即多态;

三、实例

 1、多继承,派生类有虚函数

// 基类
class baseA
{
public:
	int _ma = 1;
	int _mb = 2;
}; 

class baseB
{
public:
	int _mc = 3;
	int _md = 4;
};

// 派生类
class deriveA : public baseA, public baseB
{
public:
	virtual void print() { std::cout << "deriveA::print()\n\n\n"; }
	int _me = 3;	
	int _mf = 4;	
};

 内存分布

1>class deriveA	size(28):
1>	+---
1> 0	| {vfptr}
1> 4	| +--- (base class baseA)
1> 4	| | _ma
1> 8	| | _mb
1>	| +---
1>12	| +--- (base class baseB)
1>12	| | _mc
1>16	| | _md
1>	| +---
1>20	| _me
1>24	| _mf
1>	+---
1>
1>deriveA::$vftable@:
1>	| &deriveA_meta
1>	|  0
1> 0	| &deriveA::print

2、多继承、派生类重载基类虚函数 

// 基类
class baseA
{
public:
	virtual void show() { std::cout << "virtual baseA::show() \n\n"; }

	int _ma = 1;
	int _mb = 2;
}; 

class baseB
{
public:
	virtual void play() { std::cout << "virtual baseB::play() \n\n"; }
	int _mc = 3;
	int _md = 4;
};

class baseC
{
public:
	virtual void listening() { std::cout << "virtual baseC::listening() \n\n"; }
	int _mh = 7;
	int _mi = 8;
};

// 派生类
class deriveA : public baseA, public baseB, public baseC
{
public:
	virtual void show() { std::cout << "virtual deriveA::show() \n\n"; }//派生类即使不是虚函数,内存分布也一样
	int _me = 3;	
	int _mf = 4;	
};

 内存分布

1>class deriveA	size(44):
1>	+---
1> 0	| +--- (base class baseA)
1> 0	| | {vfptr}
1> 4	| | _ma
1> 8	| | _mb
1>	| +---
1>12	| +--- (base class baseB)
1>12	| | {vfptr}
1>16	| | _mc
1>20	| | _md
1>	| +---
1>24	| +--- (base class baseC)
1>24	| | {vfptr}
1>28	| | _mh
1>32	| | _mi
1>	| +---
1>36	| _me
1>40	| _mf
1>	+---
1>
1>deriveA::$vftable@baseA@:
1>	| &deriveA_meta
1>	|  0
1> 0	| &deriveA::show
1>
1>deriveA::$vftable@baseB@:
1>	| -12
1> 0	| &baseB::play
1>
1>deriveA::$vftable@baseC@:
1>	| -24
1> 0	| &baseC::listening
1>
1>deriveA::show this adjustor: 0

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值