Поведение виртуальной функции в С++
У меня есть вопрос, вот два класса ниже:
class Base{
public:
virtual void toString(); // generic implementation
}
class Derive : public Base{
public:
( virtual ) void toString(); // specific implementation
}
Возникает вопрос:
-
Если я хочу, чтобы подкласс класса Derive выполнял полимофизм с использованием указателя типа Base, нужно ли ключевое слово virtual в скобке?
-
Если ответ отрицательный, то какая разница между функцией-членом toString класса Derive с виртуальным и без него?
Ответы
Ответ 1
С++ 03 §10.3/2:
Если виртуальная функция-член vf объявленной в базе классов и в класс Производные, полученные непосредственно или косвенно из базы, члена функция vf с тем же именем и тот же список параметров, что и Base:: vf объявлено, то Derived:: vf также виртуальный (независимо от того, так ли это объявлено), и он переопределяет Base:: ФВ.
Ответ 2
Это ключевое слово строго необязательно и не имеет никакого значения.
Ответ 3
Свойство virtual
наследуется от базового класса и предполагается, что оно присутствует, даже если вы его не вводите.
Ответ 4
Компилятор уже знает из ключевого слова "virtual" в базовом классе, что toString является виртуальным методом. Не нужно повторять его.
Ответ 5
Функция, когда виртуальная виртуальная виртуальная.
Таким образом, в любом случае, если ключевое слово virtual не используется в последующих классах, это не препятствует переопределению функции/метода "i". Таким образом, следующее руководство может помочь в точке разработки команды: -
- Если функция/метод предполагается
переопределить, всегда использовать
ключевое слово "virtual". Это особенно
true при использовании в интерфейсе/базе
классы.
- Если производный класс должен
быть подклассифицированным в дальнейшем объяснением
укажите ключевое слово "virtual" для каждого
функции/метода, которые могут быть
переопределяется.
- Если функция/метод в производном
класс не должен быть
снова подклассифицируется, тогда ключевое слово
"виртуальный" должен быть прокомментирован
что функция/метод
был отменен, но нет
другие классы, которые его переопределяют
еще раз. Это, конечно же, не мешает
кто-то от переопределения в
производный класс, если класс
делается окончательным (не выводимым), но оно
указывает, что метод не должен быть
переопределены.
Пример:
/*virtual*/ void someFunc();
Ответ 6
Для компилятора не имеет значения, укажите ли вы виртуальное ключевое слово в производных версиях функции.
Тем не менее, это хорошая идея, чтобы поставлять его в любом случае, так что любой, кто смотрит ваш код, сможет сказать ему виртуальную функцию.
Ответ 7
Это вопрос хорошего стиля, и пользователь-программист знает, что происходит. В С++ 0x вы можете использовать [[переопределить]], чтобы сделать его более явным и видимым. Вы можете использовать [[base_check]], чтобы принудительно использовать [[переопределение]].
Если вы не хотите или не можете этого сделать, просто используйте ключевое слово virtual.
Если вы выходите без виртуального toString, и вы передаете экземпляр Derive back to Base, вызов toString() фактически вызовет Base toString(), поскольку он знает, что экземпляр Base.