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

C++のインライン仮想関数の仕組みと動作を解説

C++における仮想関数(virtual function)は、基底クラスへのポインタや参照を使って、派生クラスの種類を意識することなく各クラスのメソッドを呼び出すための仕組みです。仮想関数はコンパイル時ではなく、実行時(ランタイム)に解決されます。

仮想関数とインライン関数の役割

仮想関数の主な目的は、実行時ポリモーフィズム(動的多態性)を実現することです。一方、インライン関数はコードの実行効率を高めるために使われます。インライン関数が呼び出されると、コンパイラはその呼び出し箇所に関数のコードを直接展開します。これにより、関数呼び出しのオーバーヘッドが削減されます。

仮想関数がインライン化できる条件

ここで重要なポイントがあります。仮想関数がインライン化できるかどうかは、呼び出し方によって決まります

  • 基底クラスのポインタや参照経由で呼び出した場合: 実行時にどの派生クラスの関数が呼ばれるかが決まるため、インライン化できません。
  • オブジェクトを直接使って呼び出した場合: コンパイラがコンパイル時点でオブジェクトの正確なクラス型を把握しているため、インライン化できます。

サンプルコード

#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) {
    B b;
    D d;              // クラスDのオブジェクト
    B *bptr = &d;     // dを指すB*型のポインタ

    b.s();            // オブジェクト経由の呼び出しなのでインライン化可能
    bptr->s();        // ポインタ経由の仮想関数呼び出しのためインライン化不可

    return 0;
}

実行結果

In Base
In Derived

まとめ

このように、仮想関数はポインタや参照経由で呼び出された場合は動的ディスパッチが必要になるためインライン化されませんが、オブジェクトそのものを使って呼び出せば、コンパイラが実際のクラスを特定できるため、通常のインライン関数と同様に最適化されます。パフォーマンスが重要なコードでは、この挙動の違いを理解しておくことが大切です。

  1. C++のインライン関数とは?基本概念から実装例までわかりやすく解説

    C++におけるインライン関数(inline function)は、クラスと組み合わせてよく使われる強力な機能です。関数をインラインとして宣言すると、コンパイラはコンパイル時に関数が呼び出されるすべての場所に、その関数のコードのコピーを直接埋め込みます。 インライン関数の注意点 インライン関数に変更を加えた場合、コンパイラはすべての呼び出し箇所のコードを再度置き換える必要があるため、その関数を利用しているすべてのコードを再コンパイルしなければならない点に注意しましょう。再コンパイルを行わなければ、古い処理内容のまま動作し続けることになります。 また、コンパイラは関数の定義が複数行にわたる場合など

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

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