ためになるホームページ お問い合わせ




TOP > C++ > オーバーライドと仮想関数
オーバーライドとは?
基底クラスのメンバメソッドを継承クラスで変更する事ができる。簡単に言えば、再定義するという事。この基底クラスの関数(オーバーライドされる関数)を「仮想関数」という。
スコープ演算指定子で、基底クラスのメソッドを指定してやれば、オーバーライドする前の基底クラスのメソッドを呼び出す事ができる。
基底クラスのポインタに派生クラスのオブジェクトを代入して、アクセスした場合は、基底クラス内ではオーバーライドしたメソッドを知らないので、基底クラスのメソッドが呼び出される。

通常、オーバーライドしてもらいたいメソッドには「virtual」指定子をつけてあげる事がある。virtual指定子がなくてもオーバーライドする事は可能。
以下の例では、virtual指定子無しでの例である。

基底クラスのポインタに派生クラスのオブジェクトを代入の例
#include <iostream>
using namespace std;

class Parent
{
public:
  void func(void)
  {
    cout << "基底クラスのメソッドです" << endl;
  }
};

class Child : public Parent
{
public:
  //オーバーライドしたメソッド
  void func(void)
  {
    cout << "派生クラスのメソッドです" << endl;
  }
};

int main(int argc, char** argv)
{
  Parent *p_parent;
  Child i_child;
  p_parent = &i_child;
  i_child.func();        //オーバーライドしたメソッドを呼び出す
  i_child.Parent::func();//基底クラスのメソッドを呼び出す
  p_parent->func();      //派生クラスのオブジェクトを基底クラスのポインタに代入したメソッドを呼び出す
  return(0);
}


純粋仮想関数
ある基底クラス内のメソッドを派生クラス内で必ず実装(定義)してもらいたい場合、純粋仮想関数で宣言する。純粋仮想関数で宣言されたクラスを継承する場合、必ずオーバーライドしなければならない。
純粋仮想関数を含むクラスを「抽象クラス」と呼び、このクラスのインスタンスを作成する事はできない。よって、純粋仮想関数を継承した派生クラス内で、オーバーライドしなかった場合は派生クラスを抽象クラスとなる。いずれかの時点で、オーバーライドしてやらなくてはならない。
virtual 戻り値 メソッド名(パラメータ) = 0;

純粋仮想関数の例
#include <iostream>
using namespace std;

class Parent
{
public:
  virtual void func(void) = 0;
};

class Child : public Parent
{
};

class Grandchild : public Child
{
public:
  void func(void)
  {
    cout << "実装したメソッドです" << endl;
  }
};

int main(int argc, char** argv)
{
  //Parent i_parent; //コンパイルエラー
  //Child i_child;   //コンパイルエラー
  Grandchild i_grandchild;
  i_grandchild.func();
  return(0);
}







Copyright 2007 ためになるホームページ All Rights Reserved.