あなたが持っている:
struct Base {
virtual double Function() const;
};
struct Derived1 : Base {
virtual double Function() const;
};
struct Derived2 : Base {
virtual double Function() const;
};
あなたが欲しい:
struct Derived1 : Base {
virtual double Function(); // overrides virtual function in base
};
したがって、最初に非定数仮想関数をに追加する必要がありBase
ます。そうしないと、何もオーバーライドされません。問題は、基本クラス関数を何として定義する必要があるかということです。中断を最小限に抑えるために、非const参照を介して関数を呼び出すのと同じことを行う必要があります。つまり、const関数を呼び出します。
struct Base {
virtual double Function() const;
virtual double Function() { return static_cast<const Base*>(this)->Function(); }
};
struct Derived1 : Base {
virtual double Function() const;
virtual double Function();
};
struct Derived2 : Base {
virtual double Function() const;
// no need to override non-const Function
};
これでも既存のコードが壊れる可能性があると思います。たとえば、関数のconstバージョンとnon-constバージョンへのポインターを取得した場合、以前は同等に比較されていましたが、現在はそうではありません。
typedef double (Base::*constfunc)() const;
typedef double (Base::*mutfunc)();
((mutfunc)(constfunc(&Base::Function)) == (mutfunc(&Base::Function))); // was true, now false
クラスの一般的なユーザーにとってBase
、新しい関数を追加することはおそらく無害です。
ただし、「上記の仮想関数を使用しているが、戻り値がconstでない」と言うと、関数double
のconstバージョンを使用しても、関数の例にはすでにconst以外の戻り値()があります。したがって、回答ではこれに対処できません。実際のユースケースを隠すことで、実際のコードをより適切に反映する例よりも悪い回答が得られる可能性があります。