Странная проблема возникла, когда я пытался «решить» обычную проблему алмазную обычным способом - с использованием виртуального наследования:Алмазные суб-проблема: не-множественное наследование в побочной ветви все еще требуют конструктор класса
A
/\* both virtual
B C
\/
D
Однако мой базовый класс а не имеет конструктор по умолчанию, так что я должен был назвать его вручную из D. Однако, когда я пытаюсь добавить класс Е в этот алмаз, как C-наследуется
A
/\* both virtual
B C
\/\
D E
он по-прежнему необходимо вызвать конструктор из конструктора A в E вручную, то есть C не создает, чтобы создать A из E даже th не существует ни множественного наследования, ни алмаза A-C-E.
class A
{public:
A (int _N): N(_N) {};
void show()
{cout<<"A"<<N;}
protected:
int N;
};
class B: public virtual A
{ public:
B(int n): A(2*n) {};
void show()
{ cout<<"B"<<N;}
};
class C: public virtual A
{ public:
C(int n): A(3*n) {};
void show()
{ cout<<"C"<<N;}
};
class D: public B,C
{ public:
D(): B(1), C(2), A(3) {};
void show()
{ cout<<"D"<<N;}
};
class E: public virtual C
{ public:
E(): C(1) {};
void show()
{ cout<<"E"<<N;}
};
int main()
{D d; // OK
A *a = &d;
a->show();
E e; // NOT OK, no function A::A() to call in E::E()
A *a2 = &e;
a2->show();
return 0;
}
Можно ли решить эту проблему без вызова конструктора A из E? Мне нужно C, чтобы сделать это правильно :-).
Или это возможно, чтобы не пытаться решить проблему с бриллиантом на всех:
A A
| | no virtual at all
B C
\/\
D E
и до сих пор пытаются объявить объект класса D с двумя экземплярами, но красноречивая компилятор использовать А С при Colling из D каждый раз? Когда я пытаюсь добавить
using C::A
в декларацию D она до сих пор производит ошибку однозначна база А.
Спасибо, это понятно, так это точный смысл виртуального наследования? Теперь я вижу. Возможно, мне не нужно виртуальное наследование здесь, к сожалению, это будет неудобно (так как из E есть много производных, и каждый должен вызвать конструктор так же, как C и т. Д.). Может быть, есть способ обойти проблему с алмазом без виртуального наследования (по-разному)? – Nick
@Nick: Трудно сказать с абстрактным примером. Честно говоря, я вообще избегаю сложных иерархий наследования в коде, который я пишу. У кого-то другого может быть хорошее прагматическое решение для общего дела. –
Я думал ... ну, мне не нужно, чтобы C был ребенком А, что в моем конкретном случае. E может быть прямым потомком A (вместе с C). @James, спасибо много снова. – Nick