C++ 为什么类的常量数据成员需要在构造函数中初始化?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10647448/
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 constant data member of a class need to be initialized at the constructor?
提问by Abhineet
I want to know why constant data member of a class need to be initialized at the constructor and why not somewhere else? What is the impact of doing so and not doing so?
我想知道为什么一个类的常量数据成员需要在构造函数中初始化,为什么不在其他地方初始化?这样做和不这样做有什么影响?
I also see that only static constant integral datacan be initialized inside the class other than that non of the data members can be initialized inside the class.
我还看到,除了不能在类内部初始化数据成员之外,只能在类内部初始化静态常量整数数据。
for eg:- Suppose below is my class declaration
例如:-假设下面是我的类声明
class A{
int a; // This we can initialize at the constructor or we can set this member by calling "vSet" member function
const int b;
static const int c = 10; //This works fine
public:
A();
~A();
void vSet(int a);
int iAdd();
void vDisplay();
};
And the constructor is defined as mentioned below:-
构造函数定义如下:-
Edited Section: As previous constructor definition example was wrong
编辑部分:因为之前的构造函数定义示例是错误的
A::A():a(1),b(9){}
Please correct me if I am wrong. Thanks in advance.
如果我错了,请纠正我。提前致谢。
回答by Alok Save
A::A(){
a = 1;
b = 9; // Why we need to initialize this only at the constructor.
}
Is not initializationbut it is Assignment.a
and b
are already constructed and you assign them values in this case. The const
qualifier demands that the variable not be changed after its initialization, allowing this assignment would break that contract.
是不是初始化,但它是分配。a
并且b
已经构建并且在这种情况下您分配它们值。在const
预选赛中要求该变量未初始化之后改变,使这项任务将打破合同。
This is Initialization using Member Initialization list.
这是使用成员初始化列表的初始化。
A::A():a(1),b(9)
{}
You might want to have a look at this answer of mine to know the difference:
您可能想看看我的这个答案以了解区别:
What is the difference between Initializing and Assignment inside constructor?
As for another question, regarding only static constant integral data can be initialized inside the class, please read this answer of mine which explains in greater detail:
至于另一个问题,关于只能在类内部初始化静态常量积分数据,请阅读我的这个答案,其中更详细地解释了:
Why I can't initialize non-const static member or static array in class?
回答by Nawaz
What you're doing is not initialization. It is assignment, so b=9
will NOT even compile, because b
is a const
, so cannot be assignedany value to it. It should be initialized, and to do that, use member-initialization list as:
你所做的不是初始化。它是赋值,因此b=9
甚至不会编译,因为b
是 a const
,因此不能为其分配任何值。它应该被初始化,为此,使用成员初始化列表作为:
A::A() : a(1), b(9)
{ // ^^^^^^^^^^^^ this is called member-initialization list
}
In C++11, you can use in-place initialization as:
在 C++11 中,您可以使用就地初始化:
class A{
int a = 1; //C++11 only
const int b = 9; //C++11 only
static const int c = 10; //This works fine (both in C++03 and C++11)
//...
};
回答by juanchopanza
Because it is constant, it's value cannot be changed. Initializing anywhere else other than the constructor would mean a default initialization, followed by an assignment, which is not permitted for a constant. It would be the equivalent of doing this:
因为它是常数,所以它的值不能改变。在构造函数之外的任何其他地方初始化将意味着默认初始化,然后是赋值,这对于常量是不允许的。这相当于这样做:
const int i; // OK
i = 42; // Error!
Note that in C++11 it is perfectly OK to do this:
请注意,在 C++11 中,这样做是完全可以的:
struct Foo {
const int i=42;
const double x = 3.1416;
};
But this follows the same rules, i.e there is no assignment.
但这遵循相同的规则,即没有赋值。
回答by Gyscos
A const data is a data that can never be changed. It is initialized once, and then keeps the same value forever.
const 数据是永远无法更改的数据。它被初始化一次,然后永远保持相同的值。
Because of that, you can't just assign a value to it anywhere.
因此,您不能在任何地方为其赋值。
The constructor, however, is where initialization goes. So here, there is an exception, and you are able to assign a value to your const data. You can do this the classical way, or as many said, as initialization list.
然而,构造函数是初始化的地方。因此,这里有一个例外,您可以为 const 数据分配一个值。你可以用经典的方式来做到这一点,或者正如很多人所说的,作为初始化列表。
Now, why you can't do this in the class definition (unlike, say, Java) when the variable is not static is another problem, that I know no answer to.
现在,当变量不是静态的时,为什么不能在类定义中执行此操作(与 Java 不同)是另一个问题,我不知道答案。
回答by Christopher Creutzig
When the bodyof your constructor is entered, all members and sub-objects are already initialized. The only thing the constructor bodycan do is to changethem – and that is, obviously, not allowed for const
members.
当输入构造函数的主体时,所有成员和子对象都已初始化。构造函数体唯一能做的就是改变它们——显然,这对const
成员来说是不允许的。
You can, however, use an initializer list.
但是,您可以使用初始化列表。
回答by PaperBirdMaster
const values are meant to be rvalues, so they cannot appear on the right part of an expression due its constness.
const 值意味着是右值,因此由于其常量性,它们不能出现在表达式的右侧部分。
so, when you use this expression on the constructor's body
所以,当你在构造函数的主体上使用这个表达式时
A::A()
{
a = 1;
b = 9; // Why we need to initialize this only at the constructor.
}
You're using the const value as a lvalue, just as Als mentioned before. The fact is that you're trying to assing a new value to a variable that isn't allowed to change it's value afther it's lifetime had begun.
正如 Als 之前提到的,您将 const 值用作左值。事实是,您正在尝试为一个变量分配一个新值,该变量在其生命周期开始后不允许更改其值。
The correct way to assign values to a constant data member is in the ctor initializer list, that is, BEFORE the lifetime of the member value begins (as mentioned by Nawaz):
为常量数据成员赋值的正确方法是在 ctor 初始值设定项列表中,即在成员值的生命周期开始之前(如 Nawaz 所述):
A::A() :
a(1),
b(9)
{
}
Finally, on the C++11 standard you're allowed to initialize all data members where it was declared, just like the static const ones.
最后,在 C++11 标准上,您可以在声明它的地方初始化所有数据成员,就像静态 const 成员一样。
回答by jamesdlin
You can't initialize const
members outside of a constructor because, well, they're const. By definition, you can't modify them after they've been initialized, and after the object has been constructed, anything that tries to set the value is a modification.
您不能const
在构造函数之外初始化成员,因为它们是const。根据定义,在它们被初始化之后你不能修改它们,并且在对象被构造之后,任何试图设置该值的东西都是一种修改。