C++ 为什么声明为类成员的常量变量仍然可以修改?
如果已经赋值的常量变量仍然可以重新赋值,那么它不是常量?例如:C++ 为什么声明为类成员的常量变量仍然可以修改?,c++,c++11,initialization,declaration,C++,C++11,Initialization,Declaration,如果已经赋值的常量变量仍然可以重新赋值,那么它不是常量?例如: struct ss { const int m = 1024; ss() { } ss(int m) : m(m) { } }; ss sa; ss sb(-1); cout << sa.m << endl; cout << sb.m << endl; 这表示当类ss初始化时,使用参数m初始化其
struct ss
{
const int m = 1024;
ss()
{
}
ss(int m) : m(m)
{
}
};
ss sa;
ss sb(-1);
cout << sa.m << endl;
cout << sb.m << endl;
这表示当类ss
初始化时,使用参数m
初始化其成员m
。成员m
确实无法修改,但它可以初始化,就像任何其他const
对象一样。请注意,如果我们改为
ss(int m)
{
this->m = m;
}
然后我们会遇到一个问题,因为需要初始化ss::m
。如果ss::m
是一个具有默认构造函数的类,那么
ss(FooClass m)
{
this->m = m;
}
可以不显式初始化ss::m
(因为它只是默认构造的),但是构造函数主体中的行将被拒绝,因为它将在初始化后修改ss::m
编辑:哎呀,我不明白你原来的问题
大括号或相等的初始值设定项,如
仅在ctor初始值设定项中未提及成员时使用。换句话说,由于默认构造函数没有显式初始化
m
,因此使用值1024。但是,ss::ss(int)
确实显式初始化了m
,因此大括号或等号初始值设定项被忽略。您的示例只处理不同的初始化模式,这里没有重新分配。您看到的是构造函数初始值设定项列表优于类内成员初始值设定项的效果,我们可以从12.6.2
初始化基和成员一节第9段中看到,该段说:
如果给定的非静态数据成员同时具有
大括号或相等的初始值设定项和mem初始值设定项,初始化
执行mem初始值设定项指定的,并且
忽略成员的大括号或相等初始值设定项。[示例:给定
struct A {
int i = / some integer expression with side effects / ;
A(int arg) : i(arg) { }
// ...
};
A(int)构造函数将简单地将i初始化为arg的值,
i's brace orequal初始值设定项的副作用不会发生
地点-结束示例]
正如中所讨论的,这是一个有用的特性,因为它允许您默认成员变量,然后根据调用的构造函数重写这些默认值。重新分配?您从未重新分配它。与相关。此代码中没有分配或重新分配。只有初始化,每个变量只发生一次。对于不小心在声明时构造函数初始化器列表优先于初始化的人来说,这显然是一个不直观的陷阱代码>行,这是问题的症结所在。+1但是最后你把术语弄错了。mem initializer是构造函数初始值设定项列表中的初始值设定项。非静态数据成员初始值设定项是大括号或相等初始值设定项。
ss(FooClass m)
{
this->m = m;
}
const int m = 1024;
struct A {
int i = / some integer expression with side effects / ;
A(int arg) : i(arg) { }
// ...
};