字段初始化存在复杂的情况。简化的代码段如下(与gcc编译,已启用C ++ 11):
class One
{ public:
One()
{ Log("One::One(): GetVal() returns %d",getVal()); };
virtual int getVal() { return 0; };
};
class Two : public One
{ public:
Two()
{ Log("Two::Two(): GetVal() returns %d",getVal()); };
Two(int x) : val(x), One()
{ Log("Two::Two(%d): GetVal() returns %d",x,getVal()); };
virtual int getVal() { return val; };
int val = 1;
};
Two* two = new Two(2);
Log("final val = %d",two->getVal());
预期输出:
One::One(): GetVal() returns 2
Two::Two(2): GetVal() returns 2
final val = 2
实际输出:
One::One(): GetVal() returns 0
Two::Two(2): GetVal() returns 2
final val = 2
问题是:
为什么 val
字段未在调用父构造函数{{ 1}}?
为什么在声明行Two(int x) : val(x), One() {...}
中初始化也不起作用?
如何如何在调用父构造函数之前初始化?或者至少使const初始化程序(在字段声明中)起作用?
我猜有人会说这样的结构是个坏主意,但我确实需要这种方式-实际上,它包含一些重要数据,并且其中的“上”父类的计算方式是一定的,但对于类,必须在构造函数中设置它们,在执行父构造函数之前(它们通过One()
使用此值)。如果不可能,我至少需要默认的const初始化程序才能工作,这样我就可以做出一些解决方法,而不会因为字段值中的垃圾而崩溃。
我也曾尝试检查int val = 1;
中的getVal()
,但是它总是返回NULL,所以我无法根据实际的对象类型进行解决。