![](/img/trans.png)
[英]Move the static constant data member initialization outside the class definition
[英]In class initialization of constant member
当我专门告诉mymy
为常数值并保持50时,为什么编译器(clang)抱怨mymy
未初始化。为什么当我仍然告诉他mymy
其更改为23时,为什么呢?保持不变?
#include <iostream>
class Base
{
public:
Base(int y) : my(y) {std::cout << "Base:" << my << std::endl;}
private:
int my;
};
class Derived : public Base
{
public:
Derived() : Base(mymy), mymy(23) {std::cout << "Derived:" << mymy << std::endl;}
private:
const int mymy = 50;
};
int main()
{
Derived a;
}
奇怪的是,大肠菌科病菌没有山ick。 http://coliru.stacked-crooked.com/a/63629c2d99bf6f43 (是的,我知道将其更改为static
将解决此问题)
该标准说(§12.6.2/ 10 1 ,重点是我的):
如果给定的非静态数据成员同时具有默认成员初始化程序和mem-initializer ,则将执行由mem-initializer指定的初始化 ,并且将忽略非静态数据成员的默认成员初始化程序 。 [ 示例:已知
struct A { int i = /* some integer expression with side effects */ ; A(int arg) : i(arg) { } // ... };
A(int)
构造函数将简单地将i
初始化为arg
的值,并且不会发生i
的默认成员初始化器中的副作用。 —末例 ]
http://coliru.stacked-crooked.com/使用不会产生警告的g ++,但结果是相同的: Base
不是用50
或23
初始化,而是用0
初始化。 您可以通过在mymy
之前添加另一个属性来获得怪异的行为:
class Derived: public Base {
public:
Derived() : Base(mymy), mymymy(mymy), mymy(23) {
std::cout << "Derived:" << mymy << std::endl;
std::cout << "Derived:" << mymymy << std::endl;
}
int mymymy;
const int mymy = 50;
};
来自coliru的输出:
Base:4197208
Derived:23
Derived:4197208
Main:23
但是,如果在mymy
之后添加属性:
class Derived : public Base {
public:
Derived() : Base(mymy), mymy(23) {
std::cout << "Derived:" << mymy << std::endl;
std::cout << "Derived:" << mymymy << std::endl;
}
const int mymy = 50;
int mymymy= mymy;
};
将使用您在构造函数的member-initializer-list中提供的值:
Base:0
Derived:23
Derived:23
Main:23
关于const
限定:您始终可以在const
的member-list-initializer中初始化const
成员(这是可以与默认成员初始化程序一起对其进行初始化的唯一位置)。
我不知道标准中是否有更明确的报价单,但是§12.6.2/ 7 1 (示例非常明确):
mem初始化程序中的expression-list或braced-init-list用于根据直接初始化的8.5初始化规则来初始化指定的子对象(或在委派构造函数的情况下,是完整的类对象)。 [ 示例:
struct B1 { B1(int); /* ... */ }; struct B2 { B2(int); /* ... */ }; struct D : B1, B2 { D(int); B1 b; const int c; }; D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) { /* ... */ } D d(10);
—末例 ]
1最新的C ++ 17标准草案(N4594)。
如果使用ctor初始化器,则在类中将忽略初始化。
考虑到带有mymy
参数的基本构造函数的mymy
Derived() : Base(mymy), mymy(23) {std::cout << "Derived:" << mymy << std::endl;}
是错误的,因为派生类的数据成员尚未初始化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.