基本クラス:
class Base
{
public:
virtual int f() const
{
return 1;
}
};
派生クラス:
class Derived: public Base
{
public:
void f() const {}
};
上記のコードは、「戻り値の型が同一ではありません/共変エラー」をスローします。
私はそれに関するいくつかの議論を読みました。これは似ていますが、戻り値の型が同一/共変でない場合にコードが壊れるとだけ言っています。 戻り値の型が異なるメンバー関数をオーバーライドする
期待した動作が起こらないのはなぜですか?
予想される動作: Derived の VPTR は Base::f() を指します (仮想関数にオーバーライドが提供されていない場合に備えて読みました。Derived オブジェクトは継承されたクラス バージョンを使用するだけです)。また、名前 f() を非表示にするため、次のような呼び出しになります。
Derived x;
x.f();
Derived::f() と次のような呼び出しを呼び出す必要がありました。
x.Base::f();
Base::f() 関数を呼び出すべきでした。これはコードを壊しているようには見えません。アップキャストされた場合でも、両方のクラスの VPTR が同じ Base::f() を指しているため、コードを壊すべきではありません。
私が考えることができる唯一の理由は、そのような宣言 (同じ署名と共変/同一の戻り値の型) が仮想メソッドをオーバーライドするために予約されており、それを使用して期待どおりの動作を引き起こすことができないということです。