初始化列表 vs 构造函数赋值 vs 变量定义

Initializer list vs Constructor assignment vs variable defining

我正在尝试了解以下内容之间的真正区别 类。

class A
{
public:
    A()
    :width(500)
    ,height(300){};
    int width;
    int height;
};

class B
{
public:
    B()
    {
        width = 500;
        height = 300;
    };
    int width;
    int height;
};

class C
{
public:
    int width = 500;
    int height = 300;
};

您认为在 class 中初始化 widthheight 变量的最佳方法是什么?

我应该坚持一种方式而不是其他方式吗?

这段摘录自 Stanley B. Lippman 的 "Inside the C++ Object Model"。

You must use the member initialization list in the following cases in order for your program to compile:
1. When initializing a reference member
2. When initializing a const member
3. When invoking a base or member class constructor with a set of arguments
4. A few efficiency cases. (Here the program is correct w/o member initialization list)

对于1-3点,成员初始化列表是必须的。
对于第4点,不是强制性的。

例如(第 4 点),给定:

class Word {
   String _name;
   int _cnt;
   public:
   // not wrong, just naive ...
   Word() {
      _name = 0;
      _cnt = 0;
   }
};

Word 构造函数的实现初始化 _name 一次,然后使用赋值覆盖初始化,从而创建和销毁临时 String 对象。

一个明显更有效的实现将被编码:

// preferred implementation
Word::Word : _name( 0 )
{
    _cnt = 0;
}

由于这种优化,很多人更喜欢成员初始化列表,作为编写构造函数的默认方法。

// some insist on this coding style
Word::Word()
   : _cnt( 0 ), _name( 0 )
   {}

此时要问的一个合理问题是,成员初始化列表实际上发生了什么?

编译器遍历初始化列表,在任何显式用户代码之前以正确的顺序在构造函数中插入初始化。
比如之前的Word构造函数展开如下:

// Pseudo C++ Code
Word::Word( /* this pointer goes here */ )
{
   _name.String::String( 0 );
   _cnt = 0;
}

Note : The order in which the list entries are set down is determined by the declaration order of the members within the class declaration, not the order within the initialization list. In this case, _name is declared before _cnt in Word and so is placed first.

所以回到你的问题:

class B 很好(因为您使用的是原始数据类型)。

class A 将生成与 class B

相同的代码

至于class C,先调用默认构造函数,然后初始化widthheight。当要有超过 1 个构造函数时,应该优先使用此方法,并且对于每个构造函数,widthheight 需要默认为您想要的值。

然而,自从 C++11 出现,并使用 {} 作为统一初始化,更推荐的编写 class C 的方法是:

class C
{
    public:
    int width {500};
    int height {300};
};