Перегрузка унаследованных конструкторов
Дан следующий базовый класс:
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
и используя конструктор шаблона variadic в каждом производном классе? Есть ли менее подробный способ перегрузки унаследованных конструкторов?
Я использую C++17.
2 ответа
В этом случае все, что вам нужно сделать, это предоставить c
с инициализатором в классе
class Derived : public Base {
using Base::Base;
bool c = true;
};
позволяет использовать Base
Конструкторы и инициализируют c
в true
во всех случаях.
Кажется, что вы ищете способ наследовать Base
конструкторы при инициализации членов Derived
к чему-то конкретному. Для этого мы можем по умолчанию инициализировать член:
class Derived: public Base {
public:
using Base::Base;
private:
bool c = true;
};
Построение Derived(42)
вызовет Base(int)
конструктор, но также инициализировать c
в true
,