C++虚继承和虚函数

虚继承

虚继承和普通继承有啥区别呢,上代码

class CA
{
	int a;
}
class CB : public VA
{
	int b;
}
class CD : public CA
{
	int d;
}	
class CE :public CB, public CD
{	
	int e;
}
cout<< sizeof(CB) << endl;//输出8
cout<< sizeof(CD) << endl;//输出8
cout<< sizeof(CE) << endl;//输出20

上面CE继承于CB和CD,而CD和CB都继承于CA,在CE中就会有两个CA,不但浪费了内存,还会出现二义性的问题
那么,虚继承可以解决这个问题

class CA
{
	int a;
}
class CB: virtual public CA
{
	int b;
}
class CD : virtual public CA
{
	int d;
}
class CE :public CB,public CD
{
	int e;
}

这里他们的字节是多少呢

cout<<sizeof(CB)<<endl;//输出12
cout<<sizeof(CD)<<endl;//输出12
cout<<sizeof(CE)<<endl;//输出24

欸,怎么内存反而增加了呢,别急

在类中,只要出现了 virtual 关键字,就会增加4字节,在CE继承与CD和CB的时候,CA只进行一次拷贝,所以让我们来数一下

CA:4字节
CB:CA+virtual+4字节=12
CD:CA+virtual+4字节=12
CE是如何进行构造的呢,我们看一下类的构造顺序
1丶虚基类
2丶基类
3丶子对象
4丶自身
构造顺序如下CA->CB->CD->CE
先进入CE,由CE进入CB,CB进入CA,构造CA->构造CB;
CB构造完成,进入CD,此时CA已经由CB构造完成,不再进行构造,只构造CD;CD构造完成,构造自身CE
所以CE的大小为:CA:4+CB:8+CD:8+自身的4=24

虚函数

class CA
{
	int a;
public:
	virtual void fun(){cout<<"1>>>>>"<<endl;}
	virtual void fun(){cout<<"2>>>>>"<<endl;}
	virtual void fun(){cout<<"3>>>>>>"<<endl;}
	void afun();
}

虚函数在类中出现就会增加4字节,那么这个4字节是干什么用的呢
它是用来存储所有虚函数的首地址,我们叫它虚函数列表

我们可以用函数指针来访问到它

typedef void(*p)()

CA a;
p pfun;

for(int i=0;i<3;++i)
{
	pfun=(p)*((int *)*(int *)(&a)+i);
	pfun();
}

虚函数最大的作用是 实现多态的一个必需条件
派生类可以在类中重新定义与基类函数同名的函数,并且通过基类指针或引用访问到它
比如现在我们要做一个俄罗斯方块,方块有变形的行为,我们没必要给每一个方块都写一个变形的函数,这时可以通过虚函数来进行

class CA
{
public:
	virtual void transf(){cout<<"CA变形"<<endl}
}
class CB : public CA
{
public:
	void transf(){cout<<"CB变形"<<endl;
}
class CD :public CA
{
public:
	void transf(){cout<<"CD 变形"<<endl;
}


void transf(CA & src)
{
	src.transf();
}
CA a;
CB b;
Cd d;

transf(a);
transf(b);
transf(d);
//输出各自的变形函数

这里CA无论被继承多少次,都保持特性

class CE: public CD,public CB
{
 	void transf(){cout<<"CE变形"<<endl;	
}

transf(CE);
//这里也是一样的输出自己的变形函数


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值