コンテンツにスキップ

最終更新:2026-10-12

C++ メンバ初期化リストの注意点

C++において、クラスを正しく初期化することは、プログラムが正常に動作することを保証する重要なステップの1つです。特に初期化リストを使う際には、コードの実行過程で予期しない結果が生じるのを避けるために、いくつかの潜在的な落とし穴に注意する必要があります。

初期化リストは、クラスメンバを初期化する簡潔で効率的な方法を提供するため、新しいクラスインスタンスの状態を設定する際に第一に選ばれる方法と一般に考えられています。しかし、初期化リストの中で他のメンバ変数を参照すると、混乱を招く問題が発生する可能性があります。

問題の例

次のFooクラスを考えてみましょう:

#include <iostream>

class Foo
{
public:
  Foo(int size) : size_(size),
                 capacity_(size_ + 2),
                 length_(capacity_)
  {}

  void print() {
    std::cout << "Size: " << size_ << " Capacity:  " << capacity_ << " Length: " << length_  << std::endl;
  }

private:
  int length_;
  int capacity_;
  int size_;
};

int main() {
  Foo foo(50);
  foo.print();
}

この例では、初期化リストの中で他のメンバ変数を参照することによって、length_、capacity_、size_を初期化しようとしています。しかし、クラスメンバの初期化順序は、クラス内で宣言された順序に従って行われるため、length_とcapacity_が期待した通りに初期化されない可能性があります。

解決方法は?

このような問題を避けるために、次の点に従うべきです:

1.初期化リストの中で他のメンバ変数を参照しない

2.順序の一貫性:メンバ変数の初期化順序は、クラス内で宣言された順序に従う

修正した例:

#include <iostream>

class Foo
{
public:
  Foo(int size) : size_(size),
                 capacity_(size_ + 2),
                 length_(calculateLength(size_))
  {}

  void print() {
    std::cout << "Size: " << size_ << " Capacity:  " << capacity_ << " Length: " << length_  << std::endl;
  }

private:
  int calculateLength(int size) {
    return size + 2;
  }

private:
  int size_;
  int capacity_;
  int length_;
};

int main() {
  Foo foo(50);
  foo.print();
}

関連トピック

コメント