В целом, поскольку C++ пытается решить проблему наследования алмазов http://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem (будь то хорошее или плохое решение остается в качестве упражнения для читателя).
Все наследование представляет собой комбинацию отношений is-a и has-a ... вы должны создать экземпляр родителя. Если у вас есть следующие классы:
class a;
class b : a;
class c : a;
class d : b,c;
Затем вы создали экземпляр a для каждого b и c. d не будет знать, какой а использовать.
C++ решает это, разрешив виртуальное наследование, которое является высоконадежным наследованием, которое позволяет b и c совместно использовать один и тот же a, если унаследовано в d (это намного сложнее, чем это, но вы можете прочитать это на своем своя).
Самый производный тип в цепочке должен быть способен переопределить создание совместного класса для управления различиями в том, как общий класс наследуется родительскими классами. Рассмотрим следующий пример:
class a {int x; public: a(int xx) {x=xx;} int get_x() {return x;}};
class b : public virtual a { public: b(): a(10){}};
class c : public virtual a { public: c(): a(15){}};
class d : public virtual b, public virtual c {public: d() : a (20) {}};
int main() {
d dd;
std::cout << dd.get_x() << std::endl;//20, d's constructor "wins"
return 0;
}
Если d не определить, что a
был экземпляр, как это было бы для определения конфликтующих инстанциацию (от b
и c
). C++ обрабатывает это, заставляя наиболее производный класс в цепочке наследования создавать экземпляры всех родительских классов (выше было бы barf, если d
НЕ ЯВЛЯЕТСЯ Явным образом создавал экземпляр a
, хотя если a
предоставил конструктор по умолчанию, который может быть неявно использован) и игнорирование всех родительских экземпляров.
Нет, но виртуальная база построена по самому производному классу. –