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

C++17のインライン変数(inline variable)とは?仕組みと使い方を解説

C++では、関数に対してinlineキーワードを使用できます。そしてC++17からは、この概念が変数にも拡張され、「インライン変数(inline variable)」という新しい機能が導入されました。

インライン変数の基本的な仕組み

インライン変数は、複数の翻訳単位(translation unit)で定義することが許されている点が大きな特徴です。「1つの変数を複数回定義するとODR(One Definition Rule:一意定義ルール)に違反するのでは?」と思われるかもしれませんが、心配は不要です。インライン変数もODRに従っており、同じ変数が複数の翻訳単位で定義された場合でも、コンパイラとリンカがそれらをすべて最終的なプログラム内の1つのオブジェクトに統合してくれます。

この仕組みにより、ヘッダファイルだけで完結する自己完結型のコードが書きやすくなり、特にテンプレートライブラリやヘッダオンリー設計において非常に便利です。

C++17以前の制限:staticメンバ変数の初期化

C++17以前のC++では、クラス内でstaticメンバ変数を直接初期化することができませんでした。クラス宣言の外側で改めて定義・初期化する必要があります。

従来の書き方(C++17以前)

#include <iostream>
using namespace std;

class MyClass {
public:
    MyClass() {
        ++num;
    }
    ~MyClass() {
        --num;
    }
    static int num;   // 宣言のみ
};

int MyClass::num = 10;   // クラス外で定義・初期化が必要

int main() {
    cout << "静的メンバの値は: " << MyClass::num;
}

実行結果

静的メンバの値は: 10

このように、宣言と定義を別々の場所に書く必要があり、コードが分散してしまうのが課題でした。

C++17での改善:クラス内で直接初期化できる

C++17では、inline staticと指定することで、staticメンバ変数をクラス定義の中で直接初期化できるようになりました。

C++17での書き方

#include <iostream>
using namespace std;

class MyClass {
public:
    MyClass() {
        ++num;
    }
    ~MyClass() {
        --num;
    }
    inline static int num = 10;   // クラス内で直接初期化
};

int main() {
    cout << "静的メンバの値は: " << MyClass::num;
}

実行結果

静的メンバの値は: 10

inlineキーワードを付けることで、クラス外部への定義の記述が不要になり、コード全体がすっきりします。

まとめ

  • インライン変数はC++17で導入された新機能である
  • 複数の翻訳単位で定義しても、リンカが1つのオブジェクトに統合するためODRに違反しない
  • inline staticを使えば、staticメンバ変数をクラス内で直接初期化できる
  • ヘッダファイルだけで完結するライブラリ設計が容易になる
  1. Android Studioで静的変数(static)を使う方法と適切な活用場面を解説

    静的変数(static変数)は、クラスのインスタンスを生成しなくてもアクセスできる特殊な変数です。すべてのインスタンス間で値が共有され、プログラムの実行中に一度だけメモリへ割り当てられます。Androidアプリ開発では、ログ出力用のタグ定数やアプリ全体で共通する設定値の管理など、さまざまな場面で活用されています。この記事では、Android Studioで静的変数を宣言し、実際に使用するまでの手順をサンプルコードとともに分かりやすく解説します。静的変数とは?静的変数はクラスそのものに属し、ClassName.variableName の形式でどこからでもアクセスできます。特に static f

  2. 【初心者向け】C++の例外処理の仕組みを徹底解説!try・catch・throwの基本から独自例外の作成まで

    C++における例外処理(Exception Handling)とは、プログラムの実行中に発生するエラー(ランタイムエラー)を適切に処理するための仕組みです。例外とは、実行時に送出されるイベントのことを指し、C++ではすべての標準例外が std::exception クラスを基底クラスとして定義されています。 もし例外を捕捉しなければ、プログラムは例外メッセージを出力した後に異常終了してしまいます。例外はハンドリング可能なランタイムエラーであり、適切に処理することでプログラムの堅牢性を大きく向上させることができます。 標準例外クラスの階層構造 C++標準では、例外は <exception&