[英]initialisation of const member of base class into derive class
public:
const int x;
base():x(5){}
};
class der : public base {
public:
der():x(10){}
};
der d;
My aim is when instance of base class is created it will initialise x as 5 and when instance of der class is created it will initialise x as 10. But compiler is giving error. 我的目标是当创建基类的实例时,它将x初始化为5,当创建类的实例时,它将x初始化为10.但编译器给出了错误。 As x is inherited from class base, why is it giving error?
由于x是从类库继承的,为什么它会给出错误?
You can make this work with a little adjustment... 你可以通过一点调整来完成这项工作......
#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;
}
This provides a constructor, accessible by derived classes, that can provide a default value with which to initialise base.x
. 这提供了一个可由派生类访问的构造函数,它可以提供用于初始化
base.x
的默认值。
You can't initialize a base class member in the initializer list for a constructor in the derived class. 您无法在派生类中的构造函数的初始值设定项列表中初始化基类成员。 The initializer list can contain bases, and members in this class, but not members in bases.
初始化列表可以包含此类中的基础和成员,但不包含基础中的成员。
Admittedly, the standardese for this isn't entirely clear. 不可否认,这方面的标准并不完全清楚。 12.6.2/2 of C++03:
C ++ 03的12.6.2 / 2:
Unless the mem-initializer-id names a nonstatic data member of the constructor's class or a direct or virtual base of that class, the mem-initializer is ill-formed.
除非mem-initializer-id命名构造函数类的非静态数据成员或该类的直接或虚拟基础,否则mem-initializer是不正确的。
It means "(a nonstatic data member of the constructor's class) or (a direct or virtual base)". 它的意思是“(构造函数类的非静态数据成员)或(直接或虚拟基础)”。 It doesn't mean "a nonstatic data member of (the constructor's class or a direct or virtual base)".
它并不意味着“(构造函数的类或直接或虚拟基础)的非静态数据成员”。 The sentence is ambiguous, but if you took the second reading then you couldn't put bases in the initializer-list at all, and the very next sentence in the standard makes it clear that you can.
这个句子含糊不清,但是如果你读了二读,你根本就不能在初始化列表中放置基数,而标准中的下一个句子清楚表明你可以。
As for why it's not allowed, that's a standard rationale question and I'm guessing at the motives of the authors of the standard. 至于为什么不允许,这是一个标准的理由问题,我猜测标准作者的动机。 But basically because it's the base class's responsibility to initialize its own members, not the derived class's responsibility.
但基本上是因为基类有责任初始化自己的成员,而不是派生类的责任。
Probably you should add an int
constructor to base
. 可能你应该添加一个
int
构造函数到base
。
This works. 这有效。
class base {
public:
static const int x = 5;
};
class der : public base {
public:
static const int x = 10;
};
If you want to change x depending on your constructor, you have to make it non-static. 如果要根据构造函数更改x,则必须使其为非静态。
A non-static const is the same as a non-const variable once compiled. 一旦编译,非静态const与非const变量相同。 If you want to enforce a member variable to be read-only, use non-static const.
如果要将成员变量强制为只读,请使用非静态const。 If you want to set a constant whose scope is restricted to a single class, use static const.
如果要设置其范围仅限于单个类的常量,请使用static const。
This may be over-engineered compared the original question, but please consider: 与原始问题相比,这可能过度设计,但请考虑:
template <typename T, class C, int index=0>
// C and index just to avoid ambiguity
class constant_member {
const T m;
constant_member (T m_) :m(m_) {}
};
class base : virtual public constant_member<int, base> {
public:
base () : constant_member<int, base>(5) {}
int x () const { return constant_member<int, base>::m; }
};
class der : public base {
public:
der () : constant_member<int, base>(10) {}
};
class der2 : public der{
public:
der2 () {} // ill-formed: no match for
// constant_member<int, base>::constant_member()
};
Comment: This is verbose, non-obvious (maybe impossible to understand for beginners), and it will be very inefficient to convert to virtual
base class just to read a member variable. 评论:这是冗长的,非显而易见的(对初学者来说可能无法理解),转换为
virtual
基类只是为了读取成员变量是非常低效的。 I am not really suggesting this as a real world solution. 我并不是真的建议这是一个真实的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.