2013-08-23 8 views
8

で複数の基底クラスから継承:コメントの部分を使用するときはOKですC++、私はこのコードを試してみました同じ仮想関数名

class A 
{ 
    virtual void foo() = 0; 
}; 

class B 
{ 
    virtual void foo() = 0; 
}; 

class C : public A, public B 
{ 
    //virtual void A::foo(){} 
    //virtual void B::foo(){} 

    virtual void A::foo(); 
    virtual void B::foo(); 
}; 

void C::A::foo(){} 
void C::B::foo(){} 

int main() 
{ 
    C c; 
    return 0; 
} 

が、私はクラス宣言の外に定義を記述しようとすると、コンパイラはエラーを報告します。 私はMSVC11コンパイラを使用していますが、誰もこれを書く方法を知っていますか? コードをcppファイルに移動する必要があります。 (下記参照)関数は名前とパラメータの種類に基づいて、基本クラスの仮想関数をオーバーライドする

class A { 
    virtual void foo() = 0; 
}; 

class B { 
    virtual void foo() = 0; 
}; 

class C : public A, public B { 
    virtual void foo(); 

}; 

void C::foo(){} 
void C::A::foo(){} 
void C::B::foo(){}; 

int main() { 
    C c; 
    return 0; 
} 
+1

コメント部分はまた、GCCで動作していない2つの異なるA::fooためのオーバーライドと継承の別の層を導入するよりも、他の異なる動作をするB::fooを持ってする方法はありません。 –

+2

それはまったく意味がありません。 'virtual void foo();'と '* once * 'だけでなければなりません。 –

+0

どのように 'A'、' B'、 'C'を_useしたいですか?多くの可能性があります:[例1](http://ideone.com/KlVTgv)、[例2](http:// ideone。 –

答えて

4

を~~ありがとう。したがって、クラスCの2つの仮想関数fooを持ち、それぞれABから継承します。しかし両方をオーバーライドvoid C::foo()機能:

[class.virtual]/2

仮想メンバ関数vfクラスBaseで宣言され、クラスDerivedに、Baseから直接的または間接的に誘導された場合同じ名前のメンバ関数vfパラメータタイプリスト、cv-qualification、およびref-qualifier(またはその不在)がBase::vfと宣言されている場合、Derived::vfも同様に宣言されているかどうかed)とそれはオーバーライドBase::vfです。

I既にコメントで述べたように、[dcl.meaning]/1(メンバー)関数の宣言で修飾-IDの使用を禁止:

場合宣言子-IDしたがって任意virtual void X::foo();がillegある「

[...]宣言修飾子が参照するクラスまたは名前空間の以前に宣言されたメンバを指すもの、修飾されal内の宣言としてC

コード

class C : public A, public B 
{ 
    virtual void foo(); 
}; 

は、私の知る限りfooを上書きする唯一の方法であり、それは、A::fooB::fooの両方を上書きします。

#include <iostream> 

struct A 
{ 
    virtual void foo() = 0; 
}; 

struct B 
{ 
    virtual void foo() = 0; 
}; 

struct CA : A 
{ 
    virtual void foo() { std::cout << "A" << std::endl; } 
}; 

struct CB : B 
{ 
    virtual void foo() { std::cout << "B" << std::endl; } 
}; 

struct C : CA, CB {}; 

int main() { 
    C c; 
    //c.foo(); // ambiguous 

    A& a = c; 
    a.foo(); 

    B& b = c; 
    b.foo(); 
} 
+3

*ちょうどの発言:* 'void C :: A :: foo(){}'と 'void C :: B :: foo(){}'は純粋な仮想関数 'A :: foo 'と' B :: foo'と呼ばれます(必須ではありません)。 – dyp

+0

say ** dyp **: 'void C :: foo(){cout <<" C "<< endl;} void C :: A :: foo(){cout <<" A "<< endl ;} void C :: B :: foo(){cout << "B" << endl;}; int main(){ C c; c.foo(); ((&&)c).foo(); ((B&)c).foo(); return 0; } '**常に出力 'C' ** – biv

+0

@dyp' A :: foo() 'の定義を提供するために' void C :: A :: foo(){} 'という構文を使用することが合理的であるのか不思議です。 'A :: for(){}'を直接オーバーライドするのではなく、この種の構文を使う利点はありますか? 'A 'が内部クラスであれば、私は非常に混乱しているように見えますか?私はこのコードを編集し、それが合法であることに驚いた。 – Dreamer

15

はあなたがただ一つの仮想関数fooを持って

関連する問題