public:
const int x;
base():x(5){}
};
class der : public base {
public:
der():x(10){}
};
der d;
Run Code Online (Sandbox Code Playgroud)
我的目标是当创建基类的实例时,它将x初始化为5,并且当创建类的实例时,它将x初始化为10.但是编译器给出了错误.由于x是从类库继承的,为什么它会给出错误?
你可以通过一点调整来完成这项工作......
#include <cassert>
class base
{
public:
const int x;
base()
:x(5)
{
}
protected:
base(const int default_x)
:x(default_x)
{
}
};
class der: public base
{
public:
der()
:base(10)
{
}
};
struct der2: public base
{
der2()
:base()
{
}
};
int main()
{
base b;
assert(b.x == 5);
der d;
assert(d.x == 10);
der2 d2;
assert(d2.x == 5);
return d.x;
}
Run Code Online (Sandbox Code Playgroud)
这提供了一个可由派生类访问的构造函数,它可以提供用于初始化的默认值base.x.
您无法在派生类中的构造函数的初始化器列表中初始化基类成员。初始化列表可以包含基类和此类中的成员,但不能包含基类中的成员。
诚然,对此的标准术语尚不完全清楚。C ++ 03的12.6.2 / 2:
除非mem-initializer-id命名构造函数的类的非静态数据成员或该类的直接或虚拟基数,否则mem-initializer的格式不正确。
它的意思是“(构造函数类的非静态数据成员)或(直接或虚拟基础)”。这并不意味着“(构造函数的类或直接或虚拟基础的)非静态数据成员”。该句子是模棱两可的,但是如果您读了二读,则根本无法将基数放在initializer-list中,并且标准中的下一个句子清楚地表明您可以。
至于为什么不允许这样做,这是一个标准的基本原理问题,我猜测该标准作者的动机是什么。但是基本上是因为初始化其自己的成员是基类的责任,而不是派生类的责任。
可能您应该在中添加一个int构造函数base。