2013-03-19 7 views
0
#include<iostream> 
using namespace std; 

class base 
{ 
    public: 
     virtual void f(){} 
}; 

class middle1:public base 
{}; 

class middle2:public base 
{}; 

class derive:public middle1,public middle2 
{}; 



int main() 
{ 
    derive* pd=new derive(); 
    pd->f(); 
    return 0; 
} 

Я знаю, что виртуальный решает эту проблему, но как? Можем ли мы всегда публиковать виртуальную виртуальную информацию для безопасности, даже если у нас нет множественного наследования.В чем разница между классом A: public virtual B и классом A: public B

+0

виртуальный говорит компилятор, который принимает копию методов и переменных-членов из базы не из middle2 – Prasad

ответ

2

Каждый экземпляр derive имеет под-объект базового класса middle1 и под-объект базового класса middle2.

Если наследование не является виртуальным, то класс подобъект middle1 основы имеет класс субобъект base базовых, и класс подобъект middle2 Основания также имеет класс субобъект base базы. Следовательно, каждый экземпляр derive имеет два поднабора base, а вызов pd->f() неоднозначен - какой из объектов base вы хотите назвать f()?

Создание наследования виртуальным означает, что middle1 и middle2 будут разделять один объект base объекта derive. Это устраняет двусмысленность - есть только один объект base, который можно вызвать f().

Можем ли мы всегда писать публичный виртуальный для безопасности

Не обязательно. Там могут быть иерархии наследования, в которых вы не хотитеmiddle1 и middle2 для общего доступа к объекту base.Вы могли бы утверждать, что в таких случаях, вы не должны писать класс derive, который унаследован от обоих, но если вы в конечном итоге с этой ситуацией, то обходной путь будет сделать что-либо:

static_cast<middle1*>(pd)->f(); 
pd->middle1::f(); 

указать что вы хотите позвонить f на middle1 базового класса подъобекта или

static_cast<middle2*>(pd)->f(); 
pd->middle2::f(); 

middle2 указать.

1

Я знаю, что виртуальный решает эту проблему, но как?

virtual ключевых слова решают проблему, сделав только один главный заказ базового класса подобъекта присутствовать в иерархии наследования. Без него каждый родительский класс middle1 & middle2 имеет свою собственную копию класса base, что приводит к двусмысленности.

Можем ли мы всегда публиковать виртуальную виртуальную информацию для безопасности, даже если у нас нет множественного наследования.

Там нет оснований использовать virtual наследование, если у вас нет множественного наследования. Множественное наследование является целью существования виртуального наследования.

1

Виртуальные базовые классы реализуют дополнительный уровень косвенности для решения проблемы алмаза (см. this question).

Если вы всегда используете виртуальное наследование, вы всегда будете нести штраф за выполнение, вытекающий из этого дополнительного уровня косвенности.

Поэтому я предлагаю вам использовать виртуальное наследование только тогда, когда вам нужно.

Смежные вопросы