Так у вас и B и С одинаково наследуют A и D.
Введите промежуточный класс, наследующий от A и D (или D сделать наследником A).
Наследуйте B и C от этого промежуточного класса.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Здравствуйте, sci_reseacher, Вы писали:
_>Как сократить запись и избавиться от копирования?
_>Вот это хотелось бы довести до рабочего состояния: _>
_>auto x = isC ? new C: new B;
_>
решение в лоб (лучшее)
A *a ;
D* d;
if( !isC ){
B *p = new B;
a = p;
d = p;
}else{
C *p = new C;
a = p;
d = p;
}
d->f();
// g()
// e()
// ...
Решение поизвратнее:
D* d = isC? new C : new D;
d->f(); // g, e,..
A* a = dynamic_cast<A*>(d);
Но у меня есть встречный вопрос: Что такое виртуальный деструкторКак это всё планируется разрушать?
Если у меня есть, например, d* или что-то вроде shared_ptr<a>, то да, а так не понятно...
Или это осталось за скобками?
На закуску, жаренная гузка:
struct A { int F; };
struct D { virtual void f() = 0; };
struct B : A, D { virtual void f() { F = 1; } };
struct C : D, A { virtual void f() { F = 2; } };
int main() {
C v; // мона B v;
D* d = &v;
d->f();
A* a = dynamic_cast<A*>(d);
return a ? a->F : 0;
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, sci_reseacher, Вы писали:
_>Как сократить запись и избавиться от копирования?
1) вынести в интерфейс
class A {
public:
virtual void afterborn() // TODO переопределить в B и C
{
afterborn_f();
....
afterborn_z();
}
protected:
// если f()...z() по задумке не могут быть виртуальными, - сделать к ним внутренние интерфейсыvirtual void afterborn_f() {} // TODO обязательно переопределить!
.....
virtual void afterborn_z() {}
};
.....
A* a = isC ? new C() : new B();
a->afterborn();
К>3) вынести в ад-хок шаблон "полиморфная лямбда" К>4) вернуться к интерфейсу, сделать CRTP К>
К> static Self* newborn() { return new Self()->afterborn(); }
К>
На самом деле, у ТС уже был выделен отдельный специальный интерфейс для инициализации. Это был D.
При этом A был неполиморфным! Уж не знаю, фича ли это, и зачем нужны были отдельные классы A и D, но если предположить, что это всё не просто так, то, возможно, бывают разные версии интерфейса для использования: A1, A2, A3...
И/или разные интерфейсы инициализации, и комбинация An и Dn определяется MDT...
Соответственно, можно или в D добавить A* GetA(), ну или GetA1(), GetA2 и т. д.
Или в A добавить возможность получения интерфейса инициализации, или, как я предлагал где-то выше, можно ничего не добавлять, а переходить от D* к А* по dynamic_cast...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском