将基类的const成员初始化为派生类

use*_*379 2 c++ inheritance

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是从类库继承的,为什么它会给出错误?

Joh*_*web 7

你可以通过一点调整来完成这项工作......

#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.


Ste*_*sop 5

您无法在派生类中的构造函数的初始化器列表中初始化基类成员。初始化列表可以包含基类和此类中的成员,但不能包含基类中的成员。

诚然,对此的标准术语尚不完全清楚。C ++ 03的12.6.2 / 2:

除非mem-initializer-id命名构造函数的类的非静态数据成员或该类的直接或虚拟基数,否则mem-initializer的格式不正确。

它的意思是“(构造函数类的非静态数据成员)或(直接或虚拟基础)”。这并不意味着“(构造函数的类或直接或虚拟基础的)非静态数据成员”。该句子是模棱两可的,但是如果您读了二读,则根本无法将基数放在initializer-list中,并且标准中的下一个句子清楚地表明您可以。

至于为什么不允许这样做,这是一个标准的基本原理问题,我猜测该标准作者的动机是什么。但是基本上是因为初始化其自己的成员是基类的责任,而不是派生类的责任。

可能您应该在中添加一个int构造函数base