C++:したいので回避"無効な共変戻り値の型"を継承した教鋳造?
-
18-09-2019 - |
質問
私は非常に複雑なクラス階層の授業によって、グローバル-イシューなどによって互い:が抽象クラスA-Cを含有する方法を返しますインスタンスのCおよびます。その継承の授業に利用したいco-バリアント型で、この場合に問題私は知らないう前向き宣言を継承に関す。
I"を代理で取得します。cpp:22:エラー:無効な共変戻り値の型仮想D*B::outC()'"-エラーからコンパイラは知らないのでDラスのサブクラスC
class C;
class A {
public:
virtual C* outC() = 0;
};
class C {
public:
virtual A* outA() = 0;
};
class D;
class B : public A {
public:
D* outC();
};
class D : public C {
public:
B* outA();
};
D* B::outC() {
return new D();
}
B* D::outA() {
return new B();
}
を変更した場合、購入したの戻り値の型のB::outC()C*例の統.あいち早く入手することができB*D*として返しの種類を継承したクラスで直感的に思があること)?
解決
私はC ++で直接接続された共変のメンバーを持つことのない方法を知っています。あなたは自分自身を返す共変のどちらかでしょう層を追加するために、または実装します。
最初のオプションについては、
class C;
class A {
public:
virtual C* outC() = 0;
};
class C {
public:
virtual A* outA() = 0;
};
class BI : public A {
public:
};
class D : public C {
public:
BI* outA();
};
class B: public BI {
public:
D* outC();
};
D* B::outC() {
return new D();
}
BI* D::outA() {
return new B();
}
と第二のための
class C;
class A {
public:
C* outC() { return do_outC(); }
virtual C* do_outC() = 0;
};
class C {
public:
virtual A* outA() = 0;
};
class D;
class B : public A {
public:
D* outC();
virtual C* do_outC();
};
class D : public C {
public:
B* outA();
};
D* B::outC() {
return static_cast<D*>(do_outC());
}
C* B::do_outC() {
return new D();
}
B* D::outA() {
return new B();
}
この第二の選択肢は、(static_castをが有効であることを、いくつかの静的なチェックを)コンパイラによって暗黙的に行われているものであることに注意してください。
他のヒント
私が知る限りではありませないということなく明確なります。問題は、その定義クラス B
できない D
がクラスのサブクラス C
したことによるもので、フルの定義クラス D
, のの定義クラス D
できない B
がクラスのサブクラス A
したことによるもので、フルの定義クラス B
, ない形に依存するきっと解決の実現を支援するた宣言で前向き宣言を残念ながらを特定できない相続関係です。
ある問題とも似てないように実施する共変 clone()
法を用いたテンプレート、 を見つけ解決することができ, ものの、類似解決に失敗したのでこちらの基準は不可能で解決します。
あなたは原因クライアント側の期待にこれを行うことはできません。 Cのインスタンスを使用している場合、あなたはそれが(Dまたは他の何か)であるCの種類を伝えることはできません。ポインタにあなたはBポインタ保存(派生クラスへの呼び出しの結果をしかし、あなたはコンパイル時にそれを知っていない)場合はこのように、私はすべてのメモリのものが右になることはよく分からない。
あなたは多相型でメソッドを呼び出すと、、ランタイム環境は、オブジェクトの動的な型をチェックする必要があり、それはあなたのクラス階層に合わせてポインタを移動します。私はあなたが、共分散に依存している必要があることはよく分かりません。 これを見ています>