C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++における仮想関数とランタイムポリモーフィズムの仕組みを解説

仮想関数とは

C++の仮想関数(virtual function)を使用すると、基底クラスへのポインタのリストを作成し、派生クラスオブジェクトの実際の型を意識することなく、任意の派生クラスのメソッドを呼び出すことができます。仮想関数はコンパイル時ではなく、実行時(ランタイム)に遅延バインディングされるのが大きな特徴です。

ランタイムポリモーフィズムの実現

仮想関数の主な用途は、ランタイムポリモーフィズム(動的多態性)を実現することです。ランタイムポリモーフィズムは、基底クラス型のポインタ(または参照)を介してのみ実現できます。また、基底クラスのポインタは、基底クラス自身のオブジェクトだけでなく、派生クラスのオブジェクトも指すことができます。

以下のコード例では、基底クラスのポインタ b が、派生クラスのオブジェクト d のアドレスを保持しています。

サンプルコード

#include<iostream>
using namespace std;
class B {
    public:
        virtual void s() {
            cout<<" In Base \n";
        }
};
class D: public B {
    public:
        void s() {
            cout<<"In Derived \n";
        }
};
int main(void) {
    D d; // クラスDのオブジェクト
    B *b = &d; // dを指すB*型のポインタ
    b->s(); // "D::s() called" を出力
    return 0;
}

出力結果

In Derived

コードのポイント

このプログラムでは、ポインタ b の宣言上の型は B* ですが、実際に指しているのはクラス D のオブジェクトです。s() が基底クラスで virtual として宣言されているため、どの関数を呼ぶかはオブジェクトの実際の型に基づいて実行時に解決され、派生クラス側の D::s() が呼び出されます。そのため出力は「In Derived」となります。

もし virtual キーワードを削除すると、静的バインディングによってポインタの型に応じた B::s() が呼ばれ、出力は「In Base」に変わります。これが仮想関数による動的ディスパッチの効果であり、ランタイムポリモーフィズムの中核となる仕組みです。

  1. C++のceil関数とfloor関数の使い方をわかりやすく解説

    ceil関数とは ceil関数は、引数に渡した値以上となる整数のうち、最も小さい値(切り上げた値)を返す関数です。C++では「cmath」ヘッダーファイル内で宣言されており、引数には天井値を求めたい単一の値を指定します。なお、引数のデータ型はdouble型・float型・long double型のいずれかである必要があります。 C++におけるceil関数の構文は以下のとおりです。 double ceil(double x); float ceil(float x); それでは、ceil関数を使用した具体的なサンプルコードを見ていきましょう。 サンプルコード #include <iost

  2. C++のフレンド関数とフレンドクラスの基本を解説

    C++におけるフレンド関数(friend function)とは、クラスのスコープ外で定義される関数でありながら、そのクラスのすべてのprivateメンバーおよびprotectedメンバーにアクセスする権限を持つ特別な関数です。フレンド関数のプロトタイプ(宣言)はクラス定義の中に記述しますが、あくまで「友達」として扱われるだけであり、クラスのメンバー関数にはなりません。この点は重要なポイントです。フレンドとして指定できるものフレンドとして宣言できるのは、以下のようなものです。通常の関数関数テンプレート他のクラスのメンバー関数クラス全体(この場合、そのクラスのすべてのメンバーがフレンドになります