У меня есть два класса: Base
и Derived
. Derived
наследует все конструкторы Base
. Кроме того, у меня есть шаблонный класс Printer<T>
, который содержит ссылку на объект типа T
и имеет метод print()
, который каким-то образом печатает объект. Вот минимальная иллюстрация.Установка конструктора по умолчанию для одного типа с множественным наследованием
class Base {
public:
Base(int x) : x(x) {}
int x;
};
template<typename T>
class Printer {
public:
const T& object;
Printer(const T& object) : object(object) {}
void print() {
cout << object << endl;
}
};
class Derived : public Base {
public:
using Base::Base;
};
std::ostream& operator<<(std::ostream& out, const Derived& d) {
return out << d.x;
}
int main() {
Derived d(1);
Printer<Derived>(d).print();
}
Теперь я хотел бы избежать прямого использования Printer
и позволяют такой синтаксис: Derived d(1); d.print();
. Таким образом, я попытался наследовать Derived
также от Printer<Derived>
.
class Derived : public Base, public Printer<Derived> {
public:
typedef Printer<Derived> MyPrinter;
using Base::Base;
Derived() : MyPrinter(*this) {}
};
Теперь у меня есть проблема: Base
конструкторы ничего не знают о Printer
и, таким образом, не может инициализировать его каким-либо образом. Я также не могу использовать делегирование конструктора здесь, потому что конструктор, который используется в Derived
, фактически унаследован от Base
.
Можно ли каким-либо образом сделать конструктор по умолчанию Derived
делегированным любым другим конструктором, даже унаследованным? Или, может быть, есть несколько других шаблонов для инициализации второй базы в множественном наследовании?
Еще одна вещь, которая затвердевает, - это то, что у меня нет доступа к коду Base
и он может использовать его как есть.
UPDATE На ответ Реми Лебо в: Base
может иметь несколько конструкторов, которые я не в курсе (это шаблонный класс, а), так что я не могу реализовать все из них и должны использовать using Base::Base
идиомы.
Ответ на krzaq: Printer
На самом деле также существует множество методов, а не только print()
, поэтому внедрение класса пересылки является неприятностью, и я стараюсь избегать его.
Вы забываете о виртуальных деструкторов в ваших базовых классов. – PaulMcKenzie
Nope. Конструктор может быть делегирован только другим конструктором того же класса. И это не имеет ничего общего с конструкторами. Даже если некоторые конструкторы могут быть делегированы, факт состоит в том, что интерфейс «Base» выгравирован на камне. Что есть, то есть. Если, как вы говорите, вы можете использовать только «Base», как есть », то единственное, что вы можете сделать, это переопределить любые методы в базе, которые являются виртуальными. Вы не можете добавлять к нему какие-либо методы. Конец. –
@PaulMcKenzie Конечно, есть в реальном коде, я просто забыл о некоторых, делая этот искусственный пример. Благодарю. –