2011-02-22 11 views
3

を返す私は、コードを次ています共変仮想関数の型が問題

#include <iostream> 
using namespace std; 

class Child1 
{ 
    int i; 
}; 

class Child2 : public Child1 
{ 
    int j; 
}; 

class Base1 
{ 

public: 

    virtual Child1& getChildren() 
    { 
     cout << "Children1" << endl; 
     return children; 
    } 

private: 

    Child1 children; 
}; 

class Base2 : public Base1 
{ 

public: 

    virtual Child2& getChildren() 
    { 
     cout << "Children2" << endl; 
     return children; 
    } 

private: 

    Child2 children; 
}; 

このコードは罰金コンパイルが、私はどちらか、または両方Base1Base2(例えばタイプのオブジェクトへの参照タイプからgetChildren()の戻り値の型を変更したときにvirtual Child2 getChildren()私は、参照を使用するときに、なぜ私はこのエラーを得ていないています知ってほしい

error C2555: 'Base2::getChildren': overriding virtual function return type differs and is not covariant from 'Base1::getChildren' 

:、私は、Visual Studio 2010で次のエラーを取得しますそうでなければそれを得る。これはVS2010のバグですか? オーバーライド関数の戻り値の型は、オーバーライドされた関数の戻り値の型と同じか、関数のクラスとの共変量でなければなりません。C++標準(MicrosoftのWebサイトのthisページ)戻り値の型B :: fのクラスは、戻り値の型D :: fのクラスと同じクラスです。戻り値の型Dのクラスの明白な直接的または間接的な基底クラスです。 :fで、Dでアクセス可能です。

PS私は現時点で標準へのアクセス権を持っていないので、上の引用符を確認することはできません。

+0

オブジェクトタイプに変更するとどうなりますか? –

+0

@Daniel Hilgarth:はい。これらの2つのメソッド 'virtual Child1 getChildren()'と 'virtual Child2 getChildren()'で上記のコードをコンパイルすると、同じエラーが発生します。 –

答えて

14

あなたは、彼らが引用された他の部分逃した:関数D :: fが関数B :: Fをオーバーライドする場合は、次の基準を満たしている場合、機能の戻り値の型が共変です」を:(1)の両方がですクラスへのポインタか、文字列はstdするのstd ::文字列などの変換:: wstringのか、仮想関数の任意の文字列変換を変更する場合は、クラス「

+0

ああ!分かりました。ありがとう。 –

4

具体的なクラスではなく、参照またはポインタである必要があります。その要件は、あなたのMS見積もりの​​ "共変に"という規定の中で、とても幸せに生きることができます。 2番目の部分では、 "戻り値の型"について説明します。ポインタ型または参照型の戻り値の型のクラスコンポーネントであるため、 "返されたクラス"を避けていることに注意してください。

オブジェクトが戻ってきて、ベースクラス用に作成された既存のコードでは、それを処理したいかもしれませんが、バーチャルディスパッチによってオブジェクトの1つが得られます。オブジェクトのサイズが異なる場合、どのようにオブジェクトを格納できますか?この混乱は、間接指定によって回避されます...あなたはそれらがどこにあるか(いくつかのバッファ、共有mem、ヒープ)を決定することができ、共変の戻り値の型はそれに対するポインタまたは参照です。

0

参照は、あなたはその仮想関数のスーパークラスを変更する必要があります実際にはその仮想関数が宣言されています。文字列変換を変更している関数を使用している場所はどこでも変更する必要があります。

私の場合、それはいくつかのものを助けてくれることを願っています。