研究虚表(探索多态的原理)和菱形虚拟继承


多态——  一个接口 多种形态,


编译器在执行过程中遇到virtual关键字的时候,将自动安装动态联编需要的机制,首先为这些包含virtual函数的类(注意不是类的实例)--即使是祖先类包含虚函数而本身没有--建立一张虚拟函数表VTABLE。在这些虚拟函数表中,编译器将依次按照函数声明次序放置类的特定虚函数的地址。同时在每个带有虚函数的类中放置一个称之为vpointer的指针,简称vptr,这个指针指向这个类的VTABLE。


一般来说一个对象的大小为所有成员变量的大小,但是当存在虚函数的时候即使这个类没有任何成员变量,他的对象的大小也不为0,为一个虚函数指针的大小。
当定义父类的一个函数为虚函数时,在子类中重载这个函数,用一个父类指针指向子类对象,并调用该函数的时候,调用的是子类的函数而不是父类的。如果 搜索

父类中这个函数不是虚函数的话,调用的就是父类的函数了


菱形继承

#include<iostream>
using namespace std;

class AA
{
public:
	int _aa;
};
class BB : public AA
{
public:
	int _bb;
};
class  CC : public AA
{
public:
	int _cc;
};
class DD :public BB, public CC
{
public:
	int _dd;
};
int main()
{ 
	DD d;
	d.BB::_aa = 0;
	d.CC::_aa = 1;
	d._bb = 2;
	d._cc = 3;
	d._dd = 4;
	cout<< sizeof(d) << endl;
	return 0;
}

  我们能够看到对象d中有继承的类BB和类CC,我们能够看到菱形继承中,对象d中存在两个成员_aa,这就存在问题,当我们想要访问_a时,编译器也不会知道我们想要访问的是哪一个变量,这就说明菱形继承存在一个“数据冗余”和“二义性“的问题。那么如何解决菱形继承所存在的这种问题呢


菱形虚拟继承

#include<iostream>
using namespace std;

class AA
{
public:
	int _aa;
};
class BB :virtual public AA
{
public:
	int _bb;
};
class  CC :virtual public AA
{
public:
	int _cc;
};
class DD :public BB, public CC
{
public:
	int _dd;
};
int main()
{ 
	DD d;
	d.BB::_aa = 0;
	d.CC::_aa = 1;
	d._bb = 2;
	d._cc = 3;
	d._dd = 4;
	cout<< sizeof(d) << endl;
	return 0;
}

虚拟继承解决了这些问题  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值