Поведение виртуальной функции в С++

У меня есть вопрос, вот два класса ниже:

  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.