为什么我们不能在他们的声明中初始化班级成员?

dan*_*jar 29 c++ constructor initialization class member

我想知道为什么我们不能在他们的声明中初始化成员.

class Foo
{
    int Bar = 42; // this is invalid
};
Run Code Online (Sandbox Code Playgroud)

相当于使用构造函数初始化列表.

class Foo
{
    int Bar;
public:
    Foo() : Bar(42) {}
}
Run Code Online (Sandbox Code Playgroud)

我个人的理解是,上面的例子更具表现力和意图.此外,这是一种较短的语法.而且我没有看到任何与其他语言元素混淆的可能性.

对此有任何官方澄清吗?

Jos*_*eld 26

在C++ 11之前,无法像这样完成非静态成员的初始化.如果使用C++ 11编译器进行编译,它应该很乐意接受您提供的代码.

我想,首先不允许它的原因是因为数据成员声明不是定义.没有引入任何对象.如果您有一个数据成员,那么在您实际创建类的类型对象之前int x;,不会int创建任何对象.因此,该成员的初始化程序会产生误导.只有在构造期间才能将值分配给成员,这正是成员初始化列表的用途.

在添加非静态成员初始化之前,还有一些技术问题要解决.请考虑以下示例:

struct S {
    int i(x);
    // ...
    static int x;
};

struct T {
    int i(x);
    // ...
    typedef int x;
};
Run Code Online (Sandbox Code Playgroud)

解析这些结构时,在解析成员时i,它是一个数据成员声明(如在S)还是成员函数声明(如在T)中是不明确的.

使用添加的功能,这不是问题,因为您无法使用此parantheses语法初始化成员.您必须使用大括号或等于初始化程序,例如:

int i = x;
int i{x};
Run Code Online (Sandbox Code Playgroud)

这些只能是数据成员,因此我们不再有任何问题.

有关在提出非静态成员初始值设定项时必须考虑的问题,请参阅提案N2628.


Jam*_*nze 5

主要原因是初始化适用于对象或实例,并且在类的声明中没有对象或实例; 在你开始构建之前,你没有那个.

在这方面有一些进化.在C++ 98标准化的最后阶段,委员会已经为整数类型的静态const成员添加了这样做的可能性---主要是因为这些可以在编译器必须能够看到初始化的上下文中使用.在C++ 11中,语言已经扩展为允许在声明中指定初始化程序,但这只是一种简写 - 实际的初始化仍然发生在构造函数的顶部.

  • 数据成员的初始化也将按声明的顺序进行. (2认同)