2016-11-23 5 views
1
#include <iostream> 
using namespace std; 

class base 
{ 
public: 
    virtual void function1(){ 
     cout<<"base function1"<<endl; 
    } 
    virtual void function2()=0; 
}; 

class base2 
{ 
public: 
    virtual void function2()=0; 
}; 

class derived : public base, base2 
{ 
public: 

    void function2(){ 
    cout<<"derived function"<<endl; 
    } 
}; 

int main() 
{ 
    derived d; 
    d.function2(); 
    d.function1(); 
} 

ここでは、2つの基本クラスには、純粋仮想関数としてfunction2()が含まれています。派生クラスは、両方の基底クラスを継承します。 function2()は派生クラスで実装されています。このようなシナリオでコンパイラがあいまいさを解決する方法。入力は大歓迎です。ここで派生クラスでどのように曖昧さが解決されましたか?

+0

を探していたあなたは '派生:: function2'と'ベース呼び出す推測:: function1'、メインには曖昧 –

+0

ないが(ありません)私は心配していました。しかし、派生クラスfunction2を継承して実装していますが、両方の基本クラスが同じ関数名を持つため、コンパイラは実装を受け入れます。 –

+0

すべてのクラスは独自の '仮想関数テーブル'を持っています。基底クラスが '純仮想関数 'を持つ場合、'派生クラス 'は'純仮想関数 'を実装する必要があります。すべての '仮想関数'( '純仮想関数'を含む)は 'derived class'の表に一度リストされます。 – sameerkn

答えて

2

あいまいさはありません。 derivedfunction2()を呼び出すと、コンパイラはどの関数を呼び出すか正確に知ることができます(derivedバージョン)。 baseまたはbase2型付きポインタ/ refで呼び出すと、コンパイラは(その特定のベースの仮想関数テーブルを介して)何を呼び出すかも知っています。

曖昧さは、この場合に起こる:

class base 
{ 
public: 
    void func(){ 
     cout<<"base func"<<endl; 
    } 
}; 

class base2 
{ 
public: 
    void func(){ 
     cout<<"base2 func"<<endl; 
    } 
}; 

class derived : public base, public base2 
{ 
public: 
    void func2(){ 
     func(); // ??? which one to call ??? 
    } 
}; 

それはオリジナルケースで働く理由は、コンパイラが両方basebase2バージョンを実装するためにderived::function2を使用していることです。仮想メソッドテーブル(可能な実装の1つのみ)を使用して実装する場合、派生した各基底に対して通常は2つの仮想テーブルがあり、どちらも同じfunction2へのポインタを含んでいます。

+0

感謝axalis。しかし、私のコードではhwコンパイラが実装を受け入れるようにしています。 –

+0

@DeekshithGowdaあなたが何を求めているのか不明です。コンパイラの書き方を尋ねていますか? – EJP

1

あなたのプログラムの出力は次のようになります。

derived function 
base function1 

はまた、あなたが具体的な派生クラスのオブジェクトdを使用しているので、関数呼び出しfunction2()を解決するにはあいまいさがありません。 class derivedには独自のメンバー関数function2()があります。あなたはそのクラスのオブジェクトを介してクラスのメンバ関数を呼び出そうとしました。

私はあなたがDiamond Problem in case of Multilevel Inheritance.