2016-10-11 11 views
0

私は2つのクラスを派生させる抽象を設計するように私のプログラミングコースの宿題を持っており、その2つの派生クラスから別のクラスを派生させています。私は複数の継承で派生した基底クラスをどのように指定できますか?

これはDeadly Death of Deathの問題を引き起こします。私は最初の2つのクラスのオブジェクトを抽象クラスのポインタにインスタンス化する必要がありますが、仮想継承で解決できるものです。そして、これはどんな種類の仮想継承でも行うことはできません。したがって、複数の継承クラスが派生する基底クラスを指定する方法がある場合、それは天文学的に便利です。

例:

#include <iostream> 

using namespace std; 

class Base { 
    public: 
     virtual void foo(){}; 
     virtual void bar(){}; 
}; 

class Der1 : public Base { 
    public: 
     virtual void foo(); 

}; 

void Der1::foo() 
{ 
    cout << "Der1::foo()" << endl; 
} 

class Der2 : public Base { 
    public: 
     virtual void bar(); 
}; 

void Der2::bar() 
{ 
     cout << "Der2::bar()" << endl; 
} 

class Join : virtual Der1, virtual Der2 { 

    private: 
     int atribb; 



}; 

int main() 
{ 
     Base* obj = new Join(); 
     ((Der1 *)(obj))->foo(); 
} 

コンパイラエラー:

nueve.cpp:機能において 'INTメイン()':

nueve.cpp:43:30:エラー: 'ベース' 'Join'のあいまいな基底です。

Base * obj = new Join();

+0

純粋な仮想関数を調べ、真にBaseを持つだけでそれらを持つことを検討してください。 – UKMonkey

+0

「これはどのような種類の仮想継承でもできません」と言うとき。どういう意味ですか?私は最初、あなたのクラスでこの割り当てに仮想継承を使用することを許可していないと言っていましたが、実際には仮想継承を使用したいが、あなたがしようとしていることをやり遂げることができないということを意味するでしょうか? –

+0

"2つのクラスを派生させる抽象をデザインするように私に要求しています" - しかし、これはあなたがやったことではない、 'Base'は抽象ではない。 'Base'の関数を純粋仮想(' = 0'を加える)にする必要があります。私は、その場合でも仮想継承が必要かどうかは不明です。 –

答えて

3

仮想継承を使用します。

class Der1 : public virtual Base { 
    public: 
     virtual void foo(); 

}; 



class Der2 : public virtual Base { 
    public: 
     virtual void bar(); 
}; 

仮想場合は、基本クラスから派生しながら、例以下に示すように、宣言され、ほとんどの派生クラスのオブジェクトは、あなたのケースであいまいさを解決するのに役立ちます一つだけ、基本クラスのサブオブジェクトが含まれています。 、最終的な実行可能コードいくつかのコードの変更を行った後

コードは、サンプルの下で変更されます。子クラスを派生しながら、

は、vitualキーワードを追加しました。 派生クラスの派生中に "virtual"キーワードを削除しました。 メンバ関数を適切に呼び出すようにmainを変更しました。

#include <iostream> 

using namespace std; 

class Base { 
    public: 
     virtual void foo(){}; 
     virtual void bar(){}; 
}; 

class Der1 : public virtual Base { 
    public: 
     virtual void foo(); 

}; 

void Der1::foo() 
{ 
    cout << "Der1::foo()" << endl; 
} 

class Der2 : public virtual Base { 
    public: 
     virtual void bar(); 
}; 

void Der2::bar() 
{ 
     cout << "Der2::bar()" << endl; 
} 

class Join : public Der1, public Der2 { 

    private: 
     int atribb; 



}; 

int main() 
{ 
     Base* obj = new Join(); 
     obj->foo(); 
} 
+0

確かに。それをします。ありがとうございました。 – Naidu

1

あなたはBaseから仮想継承が適切ではないと言っているように見えるが、それは、あなたが求めているものは明らかではありません。したがって、それが正しいと仮定すると、Base* obj = new Join();Base* obj = (Der1*)new Join();に置き換えることができ、の基底のBaseオブジェクトへのポインタが得られます。同様に、それをBase* obj = (Der2*)new Join();と置き換えることができます。Baseオブジェクトのポインタは、Der2のベースになります。

関連する問題