2012-08-06 11 views
12

C++がなぜ以下の例のようなパラメータの共分散をサポートしないのか、それを実現する方法があるのか​​知りたかったのですが?パラメータのC++共分散

class base { 
public: 
virtual base* func(base * ptr) { return new base(); } 
}; 

class derived : public base { 
public: 
virtual derived* func(derived * ptr) override { return new derived(); } //not allowed 
}; 
+3

もっと興味深いのは、なぜ引数の対立関係がサポートされていないのでしょうか。 –

答えて

10

戻り値の型はbaseからderived継承しているので許容されますが、関数のパラメータが動作することはできません - すべてではないbaseのインスタンスもderivedになります。 funcbaseへのポインタで呼び出され、パラメータがderivedでない場合に起こるはずのことはありますか?最も派生した実装は呼び出し可能ではありません。

+6

これはliskov置換原則に違反します。 –

+0

回避策はありますか? Java/C#ではキャストを使うことができますが、C++ではオブジェクトがスライスされます。 – Winter

+0

@Winter値渡し以外のスライシングはありません(ここで問題となるポリモーフィック関数では値渡しが変わってしまいます)。ポインタ(質問のように)を渡すか参照/ shared_ptr/unique_ptrは他のオブジェクト指向言語のようにスライスすることなくすべて動作し、キャスト可能です。唯一の問題は、安全性を保証するためのキャストと、dynamic_castまたはstatic_castのいずれかの選択肢に至るタイプ階層に適合し、ユーザーにあなたが当てている未書き込みの契約を破らないようにする厳しい警告です。おそらくあなたはデザインの意思決定を再訪したいと考えています。 – Flexo