仮想関数はオーバーライド,すなわち基本クラスの関数を派生クラスで再定義した際に不可欠な機構である.
派生の目的として共通の基本クラスを持つ派生クラス群を基本クラスでまとめるというものがある.
このように,関数funcはBase型の参照を受けるクラスであるが,Print関数がvirtualであることから,
その実体がBaseであるかDerive1であるかDerive2であるか実行時に判断して,その実体のPrint関数を呼び出す.
virtualを付けないとBase::Printが呼ばれる.
また,他の使い方としてデータを保持するクラス(モデルともドキュメントとも言う)には基本クラスBaseでデータを保持し,
その時に必要な派生クラスでNewするという使い方がある.
このような場合,modelクラスが持つのはBase型のポインタであるが,Baseクラスで宣言されている仮想関数は,
上述のとおり派生クラスでオーバーライドされた関数を呼ぶことができる.
派生の目的として共通の基本クラスを持つ派生クラス群を基本クラスでまとめるというものがある.
class Base { virtual void Print() { std::cout << "Base" << std::endl; } }; class Derive1 : public Base { virtual void Print() { std::cout << "Derive1" << std::endl; } }; class Derive2 : public Base { virtual void Print() { std::cout << "Derive2" << std::endl; } }; void func(Base& b) { b.Print(); } int main() { Derive1 d1; Derive2 d2; func(d1); func(d2); }
このように,関数funcはBase型の参照を受けるクラスであるが,Print関数がvirtualであることから,
その実体がBaseであるかDerive1であるかDerive2であるか実行時に判断して,その実体のPrint関数を呼び出す.
virtualを付けないとBase::Printが呼ばれる.
また,他の使い方としてデータを保持するクラス(モデルともドキュメントとも言う)には基本クラスBaseでデータを保持し,
その時に必要な派生クラスでNewするという使い方がある.
class model { private: Base* data; std::vector<Base*> data_container; }
このような場合,modelクラスが持つのはBase型のポインタであるが,Baseクラスで宣言されている仮想関数は,
上述のとおり派生クラスでオーバーライドされた関数を呼ぶことができる.
コメントをかく