重载继承的构造函数

时间:2018-10-08 16:42:49

标签: c++ inheritance c++17 inherited-constructors

给出以下基类:

class Base {
    int a, b;
public:
    Base(int a, int b=42): a(a), b(b) { }
};

还有一个从基类派生的类:

class Derived: public Base {
    using Base::Base; // inherit Base constructors
    bool c;
public:
    Derived(int a): Base(a), c(true) { }
    Derived(int a, int b): Base(a, b), c(true) { }
};

有没有一种方法可以避免为Derived创建两个单独的构造函数,而是重载继承的Base构造函数以初始化Derived的额外成员?

我当时正在考虑使用这样的东西:

template <typename... Args, 
    typename std::enable_if_t<std::is_constructible_v<Base, Args&&...>, int> = 0>
explicit Derived(Args&&... args):
    Base(std::forward<Args>(args)...), c(true) {}

这很接近,但是太冗长,如果继承了基类的构造函数,则该命令将不起作用。即如果类中存在using Base::Base(那么它默认为那些构造函数,并且不初始化字段b)。

但是,如果不存在继承自基类的构造函数,即删除using Base::Base,则可以使用。


这是完成这项工作的唯一方法吗?即通过删除using Base::Base并在每个派生类中使用可变参数模板构造函数?有没有那么繁琐的方法来重载继承的构造函数?

我正在使用C ++ 17。

2 个答案:

答案 0 :(得分:2)

在这种情况下,您需要为c提供一个类内初始化程序

class Derived : public Base {
    using Base::Base;
    bool c = true;
};

允许您使用Base的构造函数,并在所有情况下都将c初始化为true

答案 1 :(得分:2)

似乎您正在寻找一种继承Base的构造函数,而只是将Derived的成员初始化为特定对象的方法。为此,我们可以使用默认的成员初始化程序:

class Derived: public Base {
public:
    using Base::Base;
private:
    bool c = true;
};

构造Derived(42)会调用Base(int)构造函数,但也会将c初始化为true