2009-05-06 10 views
1

Мне было задано в интервью, что использование виртуального ключевого слова с объявлением класса в C++, и я ответил, что виртуальное ключевое слово не может использоваться с объявлением класса в C++. Интервьюер сказал, что это возможно, и попросил меня проверить его позже.использование виртуального ключевого слова с объявлением класса

Теперь, когда я сам это проверил, я узнал, что это возможно, и это не ошибка компилятора. На самом деле, когда я делаю что-то вроде этого с компилятором Visual C++:

virtual class Test 
{ 
    int i; 
}; 

я получаю предупреждение компилятора «предупреждение C4091:„виртуальный“: игнорируется на левом„Test“, когда никакая переменная не объявлена». Я еще не смог узнать, что означает это предупреждение и в дальнейшем используется использование виртуального ключевого слова. Если нет полезного использования, то почему это разрешено в первую очередь и почему это не ошибка компилятора.

ответ

6

Это ошибка в VC++. Комо и gcc оба отклоняют код.

+0

Я не знал, что это не работает с другими компиляторами. Вы, наверное, единственный человек, который, кажется, понял мой вопрос. – Aamir

+1

Всегда стоит попробовать его на одном компиляторе. Gcc является бесплатным, и вы можете попробовать код бесплатно на Комо здесь: http://www.comeaucomputing.com/tryitout –

+2

Амир, у вас, кажется, есть два вопроса: (1) что сделал интервьюер? (2) Почему этот юридический синтаксис? Я думаю, что большинство людей пытались ответить (1), а не (2). – GrahamS

2

Вы просто не можете использовать виртуальные для класса. Он работает только для функций членов

+0

Он работает с Microsoft Visual C++ Compiler и генерирует только предупреждение, а не сообщение об ошибке, как я уже сказал. – Aamir

+0

вы можете «виртуальное наследование», но я никогда не видел виртуального ключевого слова до класса – leiz

+0

@Aamir: Компилятор VC и меньшая протяженность g ++ являются плохими выборами для компиляторов для проверки вашего кода. Если вы хотите протестировать стандартный код, проверьте, что Комо попробовал его в Интернете: http://www.comeaucomputing.com/tryitout/ –

6

виртуальных могут быть использованы при выводе из другого класса:

class Foo : public virtual Bar 
{ 
} 

Это используется, чтобы избежать нескольких версий одного и того же базового класса при использовании множественного наследования. Wikipedia имеет хорошую статью по этому вопросу.

+1

Я определенно знаю об использовании виртуального. Но, пожалуйста, посмотрите мой пример, который я дал в исходном вопросе. Я просто хочу спросить, почему это разрешено, если для этого нет никакого использования. – Aamir

1

Возможно, он имел в виду виртуальное наследование/виртуальные базовые классы? Например.

class A : virtual public B 
{ ... } 

Это было бы технически частью определения класса.

2

Вы смотрите на неудачные использования - я уверен, что интервьюер имел в виду деклараций виртуальных базовых классов, например, так:

 
    class A : virtual public B, public C { 
    ... 
    }; 

Это общий идиома и используется чтобы обойти сценарий «множественного базового класса» в розовом дереве наследования. Типичная проблема с ними заключается в том, что вы наследуете как от класса B, так и от класса C, и они имеют общий предок A. Если вы перейдете к дереву наследования, вы столкнетесь с двусмысленностью относительно того, какой экземпляр «A» вы предполагается использовать. Если B & C имеют A как виртуальный базовый класс, они будут ссылаться на тот же экземпляр A, который решает эту проблему.

Вы можете найти более исчерпывающее описание с диаграммами классов here.

+1

Как я уже ответил в другом комментарии, что я знаю об этом виде использования очень хорошо, и у меня было хорошее обсуждение с интервьюером о том, какое использование вы упоминали. Но он придумал это позже (то, что я спросил). Вполне возможно, что он сам этого не знал. :) – Aamir

1

Может ли он говорить об использовании виртуального базового класса в объявлении класса?

Как это:

class CashierQueue : virtual public Queue {}; 

Это используется в множественном наследовании, если вы хотите, чтобы избежать производного класса, имеющий несколько копий данных члена, когда он наследует от двух или более классов, которые разделяют один и тот же базовый класс.

class Queue {}; 
class CashierQueue : virtual public Queue {}; 
class LunchQueue : virtual public Queue {}; 
class LunchCashierQueue : public LunchQueue, public CashierQueue {}; 

См http://msdn.microsoft.com/en-us/library/wcz57btd(VS.80).aspx

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