仮想関数

オーバーライド

classを継承すると継承元クラスの関数が使えるので便利になりました。
ただ継承したときに処理を変更したい場合もあります。

そういう時に継承したクラスで引数と戻り値が同じ関数を再定義することができます。
これをオーバーライドと言います。

class Base
{
public:
	void Print(void) { printf("Base\n"); }
};

class Child : public Base
{
public:
	void Print(void) { printf("Child\n"); }
};

void main(void)
{
	Base base;
	Child child;

	base.Print();
	child.Print();
}

出力結果

Base
Child

 

このようにオーバーライドを使用することで関数の内容を変えることができます。

仮想関数

オーバーライドを使うことで関数の内容を変えることが出来ました。
ただこの対応では不十分な場合があります。

void main(void)
{
	Base* base = new Child;
	base->Print();
}

出力結果

Base

このように継承したクラスの実体を作成してBaseのポインタとして保持した場合。
Printを呼び出すとBaseの関数が呼び出されてしまいます。

今回のような例ではChildのポインタとして保持すればいいのですが、場合によっては継承元のクラスのポインタとして使いたいこともあります。
そんな時に使えるのが仮想関数です。

class Base
{
public:
	virtual void Print(void) { printf("Base\n"); }
};


関数の戻り値の前に virtual と記述することで仮想関数として扱われます。
仮想関数を使うことでBaseクラスのポインタに格納された場合でも継承先でオーバーライドした関数の情報を保持できるようになります。

使い方は仮想関数を定義する以外は全て同じです。

class Child : public Base
{
public:
	void Print(void) { printf("Child\n"); }
};

void main(void)
{
	Base* base = new Child;
	base->Print();
}

出力結果

Child

このように同じ関数を呼び出しているのに異なる振る舞いをすることを
多様性(ポリモーフィズム)
と呼びます。

1 2

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です