Вопрос 27: Виртуальные базовые классы
Когда два или более класса порождаются от одного общего базового класса, можно предотвратить включение нескольких копий базового класса в объект-потомок этих классов путем объявления базового класса виртуальным при его наследовании.
ПРИМЕР
#include <iostream.h>
class base {
public: int i;
};
// d1 наследует base как virtual
class d1 : virtual public base {
public: int j;
};
// d2 наследует base как virtual
class d2 : virtual public base {
public:int k;
};
// d3 наследует как d1 так и d2. Тем не менее в d3 имеется только одна копия base!
class d3 : public d1, public d2 {
public: int m;
};
int main(){
d3 d;
d.i = 10; // неопределенности нет
}
Как видно, ключевое слово virtual предшествует спецификации наследуемого класса. Оба класса d1 и d2 наследуют класс base как виртуальный. Любое множественное наследование с их участием порождает теперь включение только одной копии класса base. Поэтому в классе d3 имеется только одна копия класса base, и, следовательно, d.i = 10 не является двусмысленным выражением.
Необходимо иметь в виду еще одно обстоятельство: хотя оба класса d1 и d2 используют класс base как виртуальный, тем не менее всякий объект класса d1 или d2 будет содержать в себе base. Например, следующий код абсолютно корректен:
// определение класса типа d1
d1 myclass;
myclass.i = 100;
Обычные и виртуальные базовые классы отличаются друг от друга только тогда, когда какой- либо объект наследует базовый класс более одного раза. При использовании виртуального базового класса только одна копия базового класса содержится в объекте. В случае использования обычного базового класса в объекте могут содержаться несколько копий.