一般說來,在衍生類別中對基類成員的訪問應該是唯一的。但是由於多繼承情況下,可能造成對基類中某個成員的訪問出現了不唯一的情況,則稱為對基類成員訪問的二義性問題。
下面再討論另外一種情況下的二義實際上,在例 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();
}