关于虚继承(在钻石继承体系中,一定要用虚继承!)

在钻石继承体系中,一定要用虚继承!

1.下面的代码块儿无法通过编译,原因是,A3无法确定自己到底是用哪一个父类中的函数。

 

class A
{
public:
	virtual void f(){}
	virtual void g(){}
};

class A1 : virtual public A
{
public:
	virtual void f()
	{

	}
};
class A2:  virtual public A
{
public:
	virtual void f()
	{

	}
};

class A3 : public A1, public A2
{
};

 下面这个通过了编译。原因是,A3确定了自己的实现方式。

class A
{
public:
	virtual void f(){}
	virtual void g(){}
};

class A1 : virtual public A
{
public:
	virtual void f()
	{

	}
};
class A2:  virtual public A
{
public:
	virtual void f()
	{

	}
};

class A3 : public A1, public A2
{
public:
	virtual void f()
	{

	}
};

 下面的代码中,A3仍然无法确定自己的实现方式。但是可以定义A3的对象。这是因为每一个函数只有一个虚函数表。

class A
{
public:
	virtual void f(){}
	virtual void g(){}
};
class A1:  public A{};
class A2:  public A{};
class A3:  public A1, public A2{};

 同理,下面的代码也能通过编译:

class A
{
public:
	virtual void f(){}
	virtual void g(){}

};
class A1:  public A //不需要虚继承
{
public:
	virtual void f(){}
};
class A2:  public A //不需要虚继承
{
public:
	virtual void g(){}
};
class A3:  public A1, public A2
{

};

  同理,下面的代码也能通过编译:

class A	{ public:virtual void f(){} };
class A1: public A{};
class A2: public A{};
class A3: public A1, public A2{};

 

但是。这三种方式存在一个致命的弱点,就是,如果不用虚继承。下面的代码无法通过编译:

  A3 a3;   A& a = a3;

 用虚继承:则可通过

class A
{
public:
	virtual void f(){}
	virtual void g(){}

};
class A1:  virtual public A
{
public:
	virtual void f(){}
};
class A2:  virtual public A
{
public:
	virtual void g(){}
};
class A3:  public A1, public A2
{

};
 A3 a3;
 A& a = a3;
虚继承的含义是,不一定会为孙子类提供实现。
为孙子类提供实现的有可能是自己,也有可能是兄弟,也有可能是父类。
在钻石继承体系中,一定要用虚继承来避免在钻石体系中的二义性

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值