CPP多继承的二义性问题及示例

一般说来,在派生类中对基类成员的访问应该是唯一的。但是由于多继承情况下,可能造成对基类中某个成员的访问出现了不唯一的情况,则称为对基类成员访问的二义性问题。
下面再讨论另外一种情况下的二义实际上,在例 FabLamp中出现过这一问题,由派生类对象a在内存的布局图可见,在同一对象a中存在重名的成员函数如on()、off()和print(),因此在调用成员函数时应避免二义性问题。这里有两种不同的情况:

第一种情况, 派生类中有成员函数print(),在其两个基类中也有自己的print()成员函数,当用派生类对象a调用print()(即a.print())时, 系统将自动执行派生类中的print(),这里不会出现二义性,但是如果要执行某个基类中的print()成员函数时,必须使用作用域::区分符加以指 定,例如,a.Lamp::print(),说明调用基类Lamp中的成员函数print();
第二种情况,两个基类中都有on(),不能写成a.on(),因为这会引起二义性,系统不知道应该调用哪一个基类的on()函数,而必须用作用域区分符来指定调用哪一个基类中的on(),即:a.Fan::on(),说明调用Fan类中的成员函数on()。
由多重继承引起的二义性问题。当一个派生类从多个基类派生,而这些基类又有一个共同的基类,则对该基类中说明的成员进行访问时,可能会出现二义性。

例子:

#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

class BaseA
{
public:
    virtual void print()=0;
};

class BaseB
{
public:
    virtual void print()=0;
};

class SonC:public BaseA,public BaseB
{
public:
    virtual void BaseA::print()
    {
        cout<<"i am BaseA's son"<<endl;
    }
    virtual void BaseB::print()
    {
        cout<<"i am BaseB's son"<<endl;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{

    BaseA* ba=new SonC;
    BaseB* bb=new SonC;

    ba->print();
    bb->print();
}

posted on 2009-10-22 22:01  ATAK  阅读(501)  评论(0编辑  收藏  举报

导航