您的位置:首页 > 其它

使用虚继承消除继承二义性

2009-12-25 13:54 246 查看
问题描述:

1. 假设有基类CBase

2. 类CInherit1继承了此基类

3. 类CInherit2继承了此基类

4. 类CFinalInherit同时继承了CInherit1和CInherit2

//5. 如今要用CBase *p指针指向new CFinalInherit对象

代码如下:

#include <iostream>
using namespace std;
// 基类
class CBase
{
public:
CBase(){ cout<<"CBase constructor."<<endl; }
virtual ~CBase(){ cout<<"CBase deconstructor."<<endl; }
};
// 第一个继承类
class CInherit1
: public CBase
{
public:
CInherit1(){ cout<<"CInherit1 constructor."<<endl; }
virtual ~CInherit1(){ cout<<"CInherit1 deconstructor."<<endl; }
};
// 第二个继承类
class CInherit2
: public CBase
{
public:
CInherit2(){ cout<<"CInherit2 constructor."<<endl; }
virtual ~CInherit2(){ cout<<"CInherit2 deconstructor."<<endl; }
};
// 最终继承类
class CFinalInherit
:public CInherit1
,public CInherit2
{
public:
CFinalInherit(){ cout<<"CFinalInherit constructor."<<endl; }
~CFinalInherit(){ cout<<"CFinalInherit deconstructor."<<endl; }
};
// 入口函数
void main()
{
cout<<"调用构造函数:"<<endl;
CFinalInherit *pfi = new CFinalInherit();
cout<<endl<<"调用析构函数:"<<endl;
delete pfi;
}


上述代码实现了1~4步,输出如下:

调用构造函数:
CBase constructor.
CInherit1 constructor.
CBase constructor.
CInherit2 constructor.
CFinalInherit constructor.
调用析构函数:
CFinalInherit deconstructor.
CInherit2 deconstructor.
CBase deconstructor.
CInherit1 deconstructor.
CBase deconstructor.


如果把第五步的注释取消。即:

CBase *pfi = new CFinalInherit();

会产生错误,如下(MS VC9.0):

error C2594: “初始化”: 从“CFinalInherit *”到“CBase *”的转换不明确

这时,需要使用C++的虚继承机制来消除这种二义性。

修改CInherit[12]对CBase的继承方式为:virtual public CBase

执行结果如下:

调用构造函数:
CBase constructor.
CInherit1 constructor.
CInherit2 constructor.
CFinalInherit constructor.
调用析构函数:
CFinalInherit deconstructor.
CInherit2 deconstructor.
CInherit1 deconstructor.
CBase deconstructor.


这样就正常了,看输出结果,就可以知道virtual 继承比较“明智”。它能辨别CBase是否已经构造过了,如果是,就不需要在构造第二次了。普通继承没这功能,所以就为CInherit1构造一次后,遇到CInherit2还“紧闭着双眼”要再构造一次。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: