ネタ元 → [Tips](C# 2.0)デリゲートの共変性と反変性 (Covariance/Contravariance)
似てはいないけど同じ思いで搭載されたC++の機能に
「return-type relaxation: 戻り型の緩和」ゆーのんがあります。
基底クラスで定義された仮想関数を導出クラスで再定義する場合、
シグニチャすなわち関数名,引数の数/型/順,そして戻り値の型
を一致させなあきません。
が、戻り値の型については厳密に一致しなくても許そうって機能。
とはいえデタラメじゃ困るんで、基底Base/導出Derivedの関係があるとき、
戻り値が Base*, Base& である仮想関数を再定義すっとき
戻り値が Derived*,Derived& であっても許そう、と。
#include <iostream>
class Base {
public:
virtual void sayHello() const { std::cout << "Base says 'Hello'\n"; }
};
// DerivedはBaseから導出する
class Derived : public Base {
virtual void sayHello() const { std::cout << "Derived says 'Hello'\n"; }
};
class FooBase {
public:
// 仮想関数 create , 戻り値は Base*
virtual Base* create() { return new Base(); }
};
class FooDerived : public FooBase {
public:
// createを再定義 , 戻り値は Derived*
virtual Derived* create() { return new Derived(); }
};
int main() {
FooBase* p;
FooBase fb;
FooDerived fd;
Base* b;
p = &fb; b = p->create(); b->sayHello(); delete b;
p = &fd; b = p->create(); b->sayHello(); delete b;
}
.NET でいえば Clone() を定義する際、
class Foo : ICloneable {
// Fooはobjectなんだからいーぢゃん!
public Foo Clone() {... }
...
}
を許すよなもんですわね、許してくんないけど。