C++:在构造函数中初始化变量的位置

87 c++ constructor initialization

可能重复:
C++初始化列表

在选项1和选项2中初始化变量的优缺点是什么?

class MyClass
{
public:
    MyClass( float f, char a );
private:
    float mFloat;
    char mCharacter;
    bool mBoolean;
    int mInteger;
};

MyClass::MyClass( float f, char a ) : mFloat( f ), mBoolean( true ) // option 1.
{
    // option 2
    mCharacter = a;
    mInteger = 0;
}
Run Code Online (Sandbox Code Playgroud)

编辑:为什么选项2如此常见?

Gre*_*ell 111

简而言之,在可能的情 原因2:

  • 如果你没有在类的初始化列表中提到变量,那么构造函数将在进入你编写的构造函数体之前默认初始化它.这意味着选项2将导致每个变量被写入两次,一次用于默认初始化,一次用于构造函数体中的赋值.

  • 另外,正如mwigdahl和avada在其他答案中所提到的,const成员和引用成员只能在初始化列表中初始化.

另请注意,变量始终按照它们在类声明中声明的顺序进行初始化,而不是按照它们在初始化列表中列出的顺序进行初始化(如果启用了正确的警告,编译器将在无序写入列表时发出警告).类似地,析构函数将以相反的顺序调用成员析构函数,在类的析构函数中的代码执行后,在类声明中最后一个调用.

  • 编译器不应该能够优化不必要的自动初始化吗?我的意思是,C#和Java可以做到,C++也应该这样做,对吧? (5认同)
  • @ 0fnt,是的,C++优化了额外的初始化,这是一个非问题.不,只是因为必须以这种方式完成一些成员,并不意味着所有人都应该这样做.初始化列表是,IMO,丑陋且难以阅读. (2认同)

mwi*_*ahl 22

虽然它不适用于此特定示例,但选项1允许您初始化引用类型(或const类型的成员变量,如下所述).选项2没有.通常,选项1是更强大的方法.


Rap*_*rre 10

请参阅我的构造函数是否应使用"初始化列表"或"赋值"?

简而言之:在您的具体情况下,它不会改变任何东西.但:

  • 对于具有构造函数的类/结构成员,使用选项1可能更有效.
  • 只有选项1允许您初始化引用成员.
  • 只有选项1允许您初始化const成员
  • 只有选项1允许您使用其构造函数初始化基类
  • 只有选项2允许您初始化没有构造函数的数组或结构.

我对选项2更常见的猜测是选项1不是众所周知的,也不是它的优点.对于新的C++程序员来说,选项2的语法更自然.


Ava*_*vra 5

选项 1 允许您初始化const成员。这不能用选项 2 来完成(因为它们是分配的,而不是初始化的)。

为什么 const 成员必须在构造函数初始值设定项中初始化,而不是在其主体中初始化?