本文へスキップ
BecomeCoder

C++コース · 第10章 クラスの基礎 ― 自分だけの型を作る · レッスン40

初期化リスト ― 効率的な初期化

ブラウザで完結

導入

前レッスンではコンストラクタ本体で name = n; と代入しました。C++ には、それより望ましい「メンバ初期化リスト」という書き方があります。実務のコードでは圧倒的にこちらが使われます。

説明

コンストラクタの ) の後ろに : メンバ(値), メンバ(値) と書くのが初期化リストです。「代入」ではなく「初期化」なので、const メンバや参照メンバも初期化でき、無駄が少なくなります。

flowchart TB
  a["本体で代入:<br/>Dog(string n) { name = n; }<br/>いったん既定構築してから代入"]
  b["初期化リスト:<br/>Dog(string n) : name(n) {}<br/>最初から n で構築(推奨)"]
  a -->|"より効率的・const も可"| b
#include <iostream>
#include <string>
using namespace std;

class Circle {
private:
    const double pi;    // const メンバは初期化リストでしか初期化できない
    double radius;
public:
    Circle(double r) : pi(3.14159), radius(r) {}   // 初期化リスト
    double area() { return pi * radius * radius; }
};

int main() {
    Circle c(2.0);
    cout << c.area() << endl;   // 12.5664
    return 0;
}

メンバにデフォルト値を書いておくと、コンストラクタで触れなかったメンバはその値になります。組み合わせると初期化がすっきりします。

#include <iostream>
#include <string>
using namespace std;

class User {
public:
    string name;
    int level = 1;         // 既定値(触らなければ 1)
    User(string n) : name(n) {}   // level は既定の 1 のまま
};

int main() {
    User u("たろう");
    cout << u.name << " Lv." << u.level << endl;  // たろう Lv.1
    return 0;
}

まとめ

コンストラクタでは「本体で代入」より「初期化リスト : メンバ(値)」を優先します。const メンバや参照メンバはこれでしか初期化できません。メンバのデフォルト値と組み合わせると、意図が明確で効率的なコードになります。

実際に動かしてみよう

下のエディタにC++を書いて「コンパイル & 実行」を押すと、ブラウザ内で本物のC++コンパイラ(clang + libc++)がその場でコンパイルして実行し、出力が表示されます。std::string・vector・クラス・テンプレート・STL などモダンC++がそのまま動きます。本文の例を書き換えて試しながら進めましょう(初回だけコンパイラの読み込みに時間がかかります。以降はキャッシュされます。この回は標準入力(cin)は使わず、値はコードに直接書きます)。

C/C++ — ブラウザ内で本物のコンパイラで実行

ブラウザ内で本物のC/C++コンパイラ(clang + libc++ / WebAssembly)を動かします。構造体・malloc/free・std::string・vector・クラス・テンプレート・STL などがそのまま実行できます(初回のみコンパイラの読み込みに時間がかかります。以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。