Это не вопрос о том, как что-то сделать, я хорошо знаю о виртуальном наследовании, и я знаю несколько способов обойти эту проблему, но никто из них мне не нравится.Виртуальное наследование с абстрактным средним классом
Вот код, который не компилируется:
struct BottomClass
{
BottomClass(int& ref) : ref(ref) {}
int& ref;
};
struct MiddleClassA : virtual public BottomClass
{
MiddleClassA() /*: BottomClass()*/ {}
virtual ~MiddleClassA() = 0;
};
MiddleClassA::~MiddleClassA(){}
struct MiddleClassB : virtual public BottomClass
{
MiddleClassB() /*: BottomClass()*/ {}
virtual ~MiddleClassB() = 0;
};
MiddleClassB::~MiddleClassB(){}
struct TopClass final : public MiddleClassA, public MiddleClassB
{
TopClass(int& ref) : BottomClass(ref) {}
};
void main()
{
int someInt;
TopClass variable(someInt);
}
Что беспокоит меня, почему это не компилируется. Я знаю, что для BottomClass нет конструктора по умолчанию, и поэтому MiddleClassX плохо сформирован. Но MiddleClassX - абстрактные классы! Даже если бы я указал конструктор там, он не будет использоваться ни при каких обстоятельствах ... так почему я должен его указывать?
Я не мог даже дать разумный конструктор, потому что MiddleClassX не имеет разумной ценности, чтобы дать BottomClass.
Мой вопрос: есть ли элегантное решение этой проблемы?
У меня есть несколько решений сам, но мне не нравится ни один из них особенно:
1) я мог бы создать конструктор по умолчанию BottomClass, который использует какое-то значение для мусора, чтобы построить свою реф. И затем assert() в этом конструкторе, поэтому я знаю, что он никогда не вызывается ... Конечно, это приводит к тому, что мне приходится выполнять проверку временем всего, что должно быть ошибкой времени компиляции, и это также практически требует существования целое число мусора, чтобы получить ссылку.
2) Я мог бы передать ссылку на каждый абстрактный средний класс и использовать это ... Но это приводит к серьезному повторению информации, и когда эти цепочки становятся длинными (как и они), очень утомительно поддерживать это. Существует также удар производительности, связанный с передачей дополнительной переменной каждому классу.
(прошу прощения, если мой вопрос трудно понять - если кто-то может лучше описать мою дилемму, что было бы удивительным, я бросил вызов, чтобы поместить это в слова)
Хорошо, что я имею в виду то есть: заменить конструкторы с MiddleClassX(): BottomClass (((станд :: соиЬ << "Распечатать меня"), somegarbageint)) {} сейчас , не существует ситуации, когда «Печать меня» будет напечатана без изменения первоначальных классов. – Ace24713
Возможно, вы не помните различия между виртуальным наследованием и не виртуальным? Фактически унаследованный базовый класс требует * явной конструкции из класса EVERY по цепочке производных классов ... Моя проблема связана с этим, потому что мне нужно указывать конструктор в тех местах, где он будет вынужден переопределяться в любом случае. – Ace24713
Извините, я почти уверен, что это относится только к виртуальному наследованию. Это просто, если вы думаете, что это не так, я, вероятно, неправильно отреагировал на свой вопрос ... – Ace24713