C++ 为什么我们不能在声明时初始化类成员?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15451840/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can't we initialize class members at their declaration?
提问by danijar
I wonder if there is a reason why we can't initialize members at their declaration.
我想知道我们不能在成员声明时初始化成员是否有原因。
class Foo
{
int Bar = 42; // this is invalid
};
As an equivalent of using constructor initialization lists.
相当于使用构造函数初始化列表。
class Foo
{
int Bar;
public:
Foo() : Bar(42) {}
}
My personal understanding is that the above example is much more expressive and intentional. Moreover this is a shorter syntax. And I don't see any possibility of confusion with other language elements.
我个人的理解是,上面的例子更具表现力和意图。此外,这是一个较短的语法。而且我看不到任何与其他语言元素混淆的可能性。
Is there any official clarification about this?
官方对此有澄清吗?
采纳答案by Joseph Mansfield
The initialization of non-static members could not be done like this prior to C++11. If you compile with a C++11 compiler, it should happily accept the code you have given.
在 C++11 之前,非静态成员的初始化不能像这样完成。如果您使用 C++11 编译器进行编译,它应该很乐意接受您提供的代码。
I imagine that the reason for not allowing it in the first place is because a data member declaration is not a definition. There is no object being introduced. If you have a data member such as int x;
, no int
object is created until you actually create an object of the type of the class. Therefore, an initializer on this member would be misleading. It is only during construction that a value can be assigned to the member, which is precisely what member initialization lists are for.
我想首先不允许它的原因是因为数据成员声明不是定义。没有对象被引入。如果您有一个数据成员,例如int x;
,int
则在您实际创建类类型的对象之前,不会创建任何对象。因此,此成员上的初始化程序会产生误导。只有在构造过程中才能为成员赋值,这正是成员初始化列表的用途。
There were also some technical issues to iron out before non-static member initialization could be added. Consider the following examples:
在添加非静态成员初始化之前,还有一些技术问题需要解决。考虑以下示例:
struct S {
int i(x);
// ...
static int x;
};
struct T {
int i(x);
// ...
typedef int x;
};
When these structs are being parsed, at the time of parsing the member i
, it is ambiguous whether it is a data member declaration (as in S
) or a member function declaration (as in T
).
当解析这些结构体时,在解析成员时i
,它是数据成员声明(如 in S
)还是成员函数声明(如 in T
)是不明确的。
With the added functionality, this is not a problem because you cannot initialize a member with this parantheses syntax. You must use a brace-or-equal-initializersuch as:
使用添加的功能,这不是问题,因为您无法使用此括号语法初始化成员。您必须使用大括号或等号初始化程序,例如:
int i = x;
int i{x};
These can only be data members and so we have no problem any more.
这些只能是数据成员,所以我们不再有问题。
See the proposal N2628for a more thorough look at the issues that had to be considered when proposing non-static member initializers.
请参阅提案N2628以更全面地了解在提出非静态成员初始值设定项时必须考虑的问题。
回答by James Kanze
The main reason is that initialization applies to an object, or an instance, and in the declaration in the class there is no object or instance; you don't have that until you start constructing.
主要原因是初始化适用于一个对象或实例,而在类中的声明中没有对象或实例;在你开始构建之前你没有那个。
There's been some evolution in this regard. Already, at the very end of standardization of C++98, the committee added the possibility to do this for static const members of integral type---mainly because these can be used in contexts where the compiler must be able to see the initialization. In C++11, the language has been extended to allow specifying an initializer in the declaration, but this is just a shorthand—the actual initialization still takes place at the top of the constructor.
在这方面已经有了一些演变。在 C++98 标准化的最后,委员会已经增加了对整型类型的静态常量成员执行此操作的可能性——主要是因为这些可以在编译器必须能够看到初始化的上下文中使用. 在 C++11 中,该语言已扩展为允许在声明中指定初始化程序,但这只是一种速记——实际的初始化仍然发生在构造函数的顶部。
回答by SIVAKUMAR A
When two or more objects(instance of the class) are declared, those objects share these data members. so value can be initialized with the help of constructor. so we can't initialize the class members during declaration.
当声明两个或多个对象(类的实例)时,这些对象共享这些数据成员。因此可以在构造函数的帮助下初始化值。所以我们不能在声明期间初始化类成员。