ポリモーフィズムは、オブジェクトインスタンスではなく、ポインタと参照で機能します。
この場合、リストにはcar
派生タイプではなく、タイプのオブジェクトが含まれます。を挿入するhonda
と、パーツがコピーされcar
、残りは無視されます。これは、スライスと呼ばれることもあります。
ポリモーフィズムの場合、ポインターのリストを使用できます。
list<car*> cars {new honda};
honda * h_ptr = dynamic_cast<honda*>(cars.back()); // should be a valid pointer
注:new
私の例のようにを使用して割り当てる場合は、それらのいずれかを忘れないでください。または、生のポインターではなく、delete
スマートポインター(など)を格納してください。std::unique_ptr<car>
基本クラスのポインタを使用してオブジェクトを削除するには、仮想デストラクタも必要です。
基本クラスを抽象化することで、スライスの問題を回避できます。純粋仮想関数が含まれている場合、そのタイプのオブジェクトをインスタンス化することはできず、それらの関数をオーバーライドする派生型のみをインスタンス化できます。
class car
{
virtual ~car() {}
virtual void do_something() = 0;
};
class honda : public car
{
void do_something() {}
};
抽象インターフェースが実際に必要ない場合(たとえば、dynamic_cast
仮想関数ではなくを使用して派生クラスの機能にのみアクセスする場合)、代わりにデストラクタを純粋仮想にすることができます。その場合、派生クラスは明示的に何もオーバーライドする必要はありません。基本クラスのデストラクタは引き続き実装する必要があり、言語の癖のため、その実装はクラス定義の外にある必要があります。
class car
{
virtual ~car() = 0;
};
inline car::~car() {}
class honda : public car {};
仮想関数によるポリモーフィズムは通常、より効率的で便利であるため、これはやや珍しいアプローチです。