我想知道我们不能在声明时初始化成员是否有原因。
class Foo
{
int Bar = 42; // this is invalid
};
相当于使用构造函数初始化列表。
class Foo
{
int Bar;
public:
Foo() : Bar(42) {}
}
我个人的理解是,上面的例子更具表现力和意图。此外,这是一个较短的语法。而且我看不到与其他语言元素混淆的任何可能性。
对此有官方澄清吗?
我想知道我们不能在声明时初始化成员是否有原因。
class Foo
{
int Bar = 42; // this is invalid
};
相当于使用构造函数初始化列表。
class Foo
{
int Bar;
public:
Foo() : Bar(42) {}
}
我个人的理解是,上面的例子更具表现力和意图。此外,这是一个较短的语法。而且我看不到与其他语言元素混淆的任何可能性。
对此有官方澄清吗?
在 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,以更全面地了解在提出非静态成员初始化程序时必须考虑的问题。
主要原因是初始化适用于对象或实例,而在类中的声明中没有对象或实例;在你开始建造之前你没有那个。
在这方面有一些演变。已经在 C++98 标准化的最后阶段,委员会增加了对整数类型的静态 const 成员执行此操作的可能性——主要是因为这些可以在编译器必须能够看到初始化的上下文中使用. 在 C++11 中,该语言已扩展为允许在声明中指定初始化程序,但这只是一种简写方式——实际初始化仍然发生在构造函数的顶部。
当声明两个或多个对象(类的实例)时,这些对象共享这些数据成员。因此可以在构造函数的帮助下初始化值。所以我们不能在声明期间初始化类成员。