C++の仮想関数についてわかりやすく詳しく解説

C++において、仮想関数はオブジェクト指向プログラミングの重要な概念です。

この記事では、C++の仮想関数について詳しく解説します。

目次から探す

C++の仮想関数とは何か?

C++の仮想関数とは、オブジェクト指向プログラミングにおいて、ポリモーフィズム(多様性)を実現するための重要な概念です。

通常の関数は、コンパイル時に呼び出す関数が決定されます。しかし、仮想関数は実行時に呼び出す関数が決定されるため、オブジェクト指向プログラミングにおいて非常に重要な役割を果たします。

例えば、以下のような継承関係があった場合を考えてみましょう。

class Animal {
public:
    virtual void speak() {
        std::cout << "Animal speaks" << std::endl;
    }
};

class Dog : public Animal {
public:
    void speak() override {
        std::cout << "Dog barks" << std::endl;
    }
};

class Cat : public Animal {
public:
    void speak() override {
        std::cout << "Cat meows" << std::endl;
    }
};

この場合、Animalクラスを継承したDogクラスとCatクラスでspeak()メソッドをオーバーライドしています。そして、以下のようにそれぞれのインスタンスを生成してspeak()メソッドを呼び出してみます。

int main() {
    Animal* animal1 = new Dog();
    Animal* animal2 = new Cat();

    animal1->speak(); // "Dog barks"
    animal2->speak(); // "Cat meows"

    delete animal1;
    delete animal2;

    return 0;
}

この結果「Dog barksCat meowsという文字列が表示されます。これは、仮想関数によって実行時に適切なメソッドが呼び出されたからです。つまり、ポリモーフィズムが実現されていることがわかります。

仮想関数の基本的な使い方

C++において、仮想関数はポリモーフィズム(多様性)を実現するための重要な概念です。

仮想関数は、基底クラスで定義された関数を派生クラスで再定義することができます。このようにして、同じ名前の関数でも異なる動作をするようになります。

以下は、仮想関数の基本的な使い方の例です。

#include <iostream>

class Animal {
public:
    virtual void speak() {
        std::cout << "Animal speaks!" << std::endl;
    }
};

class Dog : public Animal {
public:
    void speak() override {
        std::cout << "Woof!" << std::endl;
    }
};

int main() {
    Animal* animal = new Animal();
    animal->speak();

    Dog* dog = new Dog();
    dog->speak();

    Animal* animal2 = new Dog();
    animal2->speak();

    delete animal;
    delete dog;
    delete animal2;
}

上記のコードでは、Animal クラスと Dog クラスを定義しています。Animal クラスには speak() という仮想関数があります。この関数は、Animal speaks!という文字列を出力します。

一方、Dog クラスでは speak() 関数をオーバーライドし、Woof!という文字列を出力するようにしています。

そして、main 関数内で Animal クラスと Dog クラスのインスタンスを生成し、それぞれ speak() 関数を呼び出しています。また、animal2 変数に Dog クラスのインスタンスを代入し、その後も speak() 関数を呼び出しています。

実行結果は以下の通りです。

Animal speaks!
Woof!
Woof!

このように、仮想関数を使用することでポリモーフィズムが実現されており、同じ名前の関数でも異なる動作が可能になっています。

仮想関数の実装方法

C++の仮想関数は、クラス内で定義された関数にvirtualキーワードを付けることで実現できます。

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

class Derived : public Base {
public:
    void func() override {
        std::cout << "Derived::func()" << std::endl;
    }
};

上記の例では、BaseクラスとDerivedクラスが定義されています。Baseクラスのfunc()関数にvirtualキーワードが付けられており、これによってDerivedクラスでオーバーライドすることが可能になっています。

また、Derivedクラスでオーバーライドする場合は、overrideキーワードを付けることが推奨されています。これによって、誤ってオーバーライドしていない場合やシグネチャが異なる場合にコンパイルエラーを発生させることが出来ます。

int main() {
    Base* b = new Derived();
    b->func(); // "Derived::func()" が出力される
}

上記の例では、ポリモーフィズムを利用してBase型のポインタ変数bDerived型のインスタンスを代入し、そのまま呼び出しています。

この場合、実行時にbが指すオブジェクトのメソッドが呼び出されるため、Derived::func()が出力されます。

1 2

この記事のページ一覧
  1. 現在のページ
目次から探す