仮想メソッドとのインターフェースがあるとしますが、引数の1つは次のとおりです。
virtual void Delete(ParentClass *parentClass) = 0;
後でこれを子クラスに実装すると
void Delete(ChildClass *childClass)
{
};
...これが実装として機能しないのはなぜですか?
仮想メソッドとのインターフェースがあるとしますが、引数の1つは次のとおりです。
virtual void Delete(ParentClass *parentClass) = 0;
後でこれを子クラスに実装すると
void Delete(ChildClass *childClass)
{
};
...これが実装として機能しないのはなぜですか?
関数プロトタイプが異なるため (1 つは使用ParentClass
し、もう1 つはChildClass
)、それらは同じ関数ではありません。代わりに、ChildClass
引数を持つものはオーバーロードされており、関数をオーバーライドしていませんDelete
。
C++03 標準: 10.3/2
仮想メンバー関数
vf
がクラス内で宣言され、クラス内で宣言されているBase
ものと同じ名前と同じパラメーター リストを持つメンバー関数Derived
から直接的または間接的に派生する場合、オーバーライドする仮想メンバー関数でもあります。Base
vf
Base::vf
Derived::vf
Base::vf
太字のテキストに注意してください。派生クラス関数は、 Co-Variant
の戻り値の型を除いて基本クラス関数と同じシグネチャを持つ場合にのみ、基本クラス関数をオーバーライドします。関数は基本クラスと派生クラスで同じシグネチャを持っていないため、派生クラス関数は基本クラス関数をオーバーライドしていませんが、得られるのは単にFunction Hidingです。Delete()
C++03 標準: 3.3.7/1:
ネストされた宣言領域または派生クラスで同じ名前を明示的に宣言することにより、名前を非表示にすることができます。
基本クラス関数の引数として受け入れられる型は、その関数のオーバーライドでも受け入れられる必要があるためです。これにより、次のようなエラーが防止されます。
struct BastardClass : ParentClass {} wrong;
Delete(&wrong);
を期待するオーバーライドにディスパッチするChildClass
と、オブジェクトが間違った型として解釈されます。
(これは反変性として知られています-より具体的な型によってオーバーライドされる関数への引数は、オーバーライドされるものよりも具体的であってはなりません。同様の理由で、戻り値の型は共変でなければなりません -より具体的な型によってオーバーライドされる関数によって指定されたものは、それほど具体的ではありません。)