0

仮想メソッドとのインターフェースがあるとしますが、引数の1つは次のとおりです。

virtual void Delete(ParentClass *parentClass) = 0;

後でこれを子クラスに実装すると

void Delete(ChildClass *childClass)
{
};

...これが実装として機能しないのはなぜですか?

4

3 に答える 3

1

関数プロトタイプが異なるため (1 つは使用ParentClassし、もう1 つはChildClass)、それらは同じ関数ではありません。代わりに、ChildClass引数を持つものはオーバーロードされており、関数をオーバーライドしていませんDelete

于 2012-08-27T14:22:23.730 に答える
0

C++03 標準: 10.3/2

仮想メンバー関数vfがクラス内で宣言され、クラス内で宣言されているBaseもの同じ名前と同じパラメーター リストを持つメンバー関数Derivedから直接的または間接的に派生する場合、オーバーライドする仮想メンバー関数でもあります。Basevf Base::vfDerived::vfBase::vf

太字のテキストに注意してください。派生クラス関数は、 Co-Variant
の戻り値の型を除いて基本クラス関数と同じシグネチャを持つ場合にのみ、基本クラス関数をオーバーライドします。関数は基本クラスと派生クラスで同じシグネチャを持っていないため、派生クラス関数は基本クラス関数をオーバーライドしていませんが、得られるのは単にFunction Hidingです。Delete()

C++03 標準: 3.3.7/1:

ネストされた宣言領域または派生クラスで同じ名前を明示的に宣言することにより、名前を非表示にすることができます。

于 2012-08-27T15:04:02.520 に答える
0

基本クラス関数の引数として受け入れられる型は、その関数のオーバーライドでも受け入れられる必要があるためです。これにより、次のようなエラーが防止されます。

struct BastardClass : ParentClass {} wrong;
Delete(&wrong);

を期待するオーバーライドにディスパッチするChildClassと、オブジェクトが間違った型として解釈されます。

(これは反変性として知られています-より具体的な型によってオーバーライドされる関数への引数は、オーバーライドされるものよりも具体的であってはなりません。同様の理由で、戻り値の型は共変でなければなりません -より具体的な型によってオーバーライドされる関数によって指定されたものは、それほど具体的ではありません。)

于 2012-08-27T15:12:45.267 に答える