10

初期化子リストに含める必要のないクラスメンバー変数を初期化子リストに入れることに何か利点はありますか?例:

class Foo
{
public:
  Foo() {}
};

class Bar
{
public:
  Bar() : _foo() {}

private:
  Foo _foo;
};

この場合、コンパイラは何か特別なことをしますか?

4

4 に答える 4

11

この場合、違いはありません。

しかし、そうすることは有用です。
多数のメンバーがある場合、すべてのメンバーではなく一部のメンバーがリストに含まれていると、混乱が生じる可能性があります。また、初期化の順序を頭の中で強化します (順序はクラスでの宣言の順序によって定義されますが、すべてのメンバー変数が互いに並んで宣言されているわけではない大きなクラスでこの順序を視覚化すると便利です)。

注: インターナライザー リストでそれらを間違った順序で配置した場合、これは通常、ほとんどのコンパイラで単なる警告です (警告をエラーとしてコンパイルする場合を除きます (そうするべきです))。

本当の危険は、POD メンバーとコンパイラー生成コンストラクターを持つクラスにあります。

class NewFoo
{
      int x;
      int y;
};
// Version 1:
class Bar1
{
     NewFoo  f;
};
// Version 2:
class Bar2
{
     NewFoo  f;
     public:
         Bar2()  // f not in list.
         {}
};
// Version 3:
class Bar3
{
     NewFoo  f;
     public:
         Bar3()
            : f()
         {}
};

int main()
{
     Bar1     b1a;           // x and y not  initialized.
     Bar1     b1b = Bar1();  // x and y zero initialized.
     Bar2     b2a;           // x and y not  initialized.
     Bar2     b2b = Bar2();  // x and y not  initialized.
     Bar3     b3a;           // x and y zero initialized.
     Bar3     b3b = Bar3();  // x and y zero initialized.
}
于 2012-11-05T18:58:17.183 に答える
9

初期化子リストは、コンストラクターでメンバーを初期化するための推奨される方法です。これは、参照メンバーと定数メンバーを初期化する唯一の方法です。

また、初期化子リストを使用することで、初期化される前に変数を誤って使用する可能性を減らします。これは、初期化せずに変数を定義しないというより大きな哲学の一部です。

于 2012-11-05T18:39:50.397 に答える
7

使用されているコンストラクターの初期化リストに記載されていないメンバーは、デフォルトで初期化されます。これはFoo、デフォルトのコンストラクターが呼び出されることを意味します。

明示的なデフォルト コンストラクターをまったく指定Bar() : _foo() { }しない場合との違い(つまり、お使いのバージョンには単純なデフォルト コンストラクターがないということです。したがって、コンストラクターを完全に省略した場合とは値が異なりますが、それ以外の動作は同じです。 .BarBar() = defaultstd::is_trivially_constructible<Bar>::value

于 2012-11-05T18:45:36.367 に答える
1

いいえ、この場合は何も変わりません。これを行うことにメリットはありません。

于 2012-11-05T18:38:42.797 に答える