32

我想知道我们不能在声明时初始化成员是否有原因。

class Foo
{
    int Bar = 42; // this is invalid
};

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

class Foo
{
    int Bar;
public:
    Foo() : Bar(42) {}
}

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

对此有官方澄清吗?

4

3 回答 3

28

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

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

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

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

struct T {
    int i(x);
    // ...
    typedef int x;
};

在解析这些结构时,在解析 memberi时,它是数据成员声明(如S)还是成员函数声明(如T)是模棱两可的。

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

int i = x;
int i{x};

这些只能是数据成员,所以我们没有问题了。

请参阅提案N2628,以更全面地了解在提出非静态成员初始化程序时必须考虑的问题。

于 2013-03-16T16:59:17.310 回答
5

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

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

于 2013-03-16T16:55:14.083 回答
-2

当声明两个或多个对象(类的实例)时,这些对象共享这些数据成员。因此可以在构造函数的帮助下初始化值。所以我们不能在声明期间初始化类成员。

于 2018-12-28T06:21:21.067 回答