Applistar

6. 6 仮想関数

  6. 6 仮想関数  

6. 6 仮想関数

C++ には、演算子のオーバロード(overload of operator) という機能があります。これは同じ演算子や関数でも、引数の数や型によって、 その意味(実際の働き)を変えることが出来るという機能です。 あるいは意味は同じでも、引数の型によって、 実際の演算方法を別々に定義する、というような使い方をします。

関数については、このオーバロードとは少し違った機能があります。 つまり、名前と引数が同じでも、更にその中身を 「動的に変える」ことが出来ます。 そのような関数を仮想関数と言います。 外見が同じで中身が違うと いうことで、仮想的な関数という名前になっています。

ここで「動的に変える」というのは、呼ぶ方で同じ記述をしていても、それが呼ばれ る場合によって中身(呼ばれる先)が変るというような意味です。

何のためにこの仮想関数があるか、というと、「インタフェースを共有する」 ためと言われます。以下にもう少し説明を加えます。

6. 6. 1 仮想関数の作り方

基底クラスでメンバ関数を定義する時に virtual を付けます。

class base {
        public: virtual void func() {
                cout << "base::" << endl;
        }
}

あるいは、その派生クラスで同じ名前を定義します。

class derive : base
        {
        public:         void func() {
                cout << "derive::" << endl;
        }
}

6. 6. 2 仮想関数の利用方法

派生クラスで同じ名前で定義すると、それも仮想関数になります。 呼出し時に、動的にどちらを呼ぶか切替えます。

6. 6. 3 仮想関数の機能

ポインタ→関数();

という記述をした時に、 そのポインタが指しているオブジェクトが、実際には どのクラスで作られたものかを調べて、そのクラスに 同じ名前の仮想関数が定義されているなどすると、 動的に切替えることが出来ます。

6. 6. 4 純粋仮想関数

仮想関数の定義時に、 = 0 を後に付けると、純粋仮想関数 と呼ばれるものになります。

純粋仮想関数は、 「基底クラスで定義を省いても良い」 「定義のない仮想関数があってもいい」 という性質があります。

これは SystemC のインタフェース定義時に使われる形と なります。

class mem_if : virtual public sc_interface
{
public:
  virtual void writeDirect(int&, int *) = 0;
  virtual void readDirect(int&, int *) = 0;
};
  6. 6 仮想関数