Разница между виртуальной функцией и чистой виртуальной функцией

Возможный дубликат:
Виртуальный/Чистый виртуальный пояс С++

В чем разница между чистой виртуальной функцией и виртуальной функцией?

Я знаю, что "Чистая виртуальная функция - это виртуальная функция без тела", но что это значит и что на самом деле выполняется по следующей строке:

virtual void virtualfunctioname() = 0

Ответ 1

Виртуальная функция делает свой класс полиморфным базовым классом. Производные классы могут переопределять виртуальные функции. Виртуальные функции, вызываемые с помощью указателей/ссылок базового класса, будут разрешены во время выполнения. То есть динамический тип объекта используется вместо его статического типа:

 Derived d;
 Base& rb = d;
 // if Base::f() is virtual and Derived overrides it, Derived::f() will be called
 rb.f();  

Чистая виртуальная функция - это виртуальная функция, объявление которой заканчивается на =0:

class Base {
  // ...
  virtual void f() = 0;
  // ...

Чистая виртуальная функция неявно делает класс определенным для абстрактного (в отличие от Java, где у вас есть ключевое слово, чтобы явно объявить абстрактный класс). Абстрактные классы не могут быть созданы. Производные классы должны переопределять/реализовывать все наследуемые чистые виртуальные функции. Если они этого не сделают, они тоже станут абстрактными.

Интересной "особенностью" С++ является то, что класс может определять чистую виртуальную функцию с реализацией. (Что это хорошо для дискуссионных.)


Обратите внимание, что С++ 11 применил новое использование для ключевых слов delete и default, которое похоже на синтаксис чистых виртуальных функций:

my_class(my_class const &) = delete;
my_class& operator=(const my_class&) = default;

См. этот вопрос и этот для получения дополнительной информации об этом использовании delete и default.

Ответ 2

Для виртуальной функции вам необходимо обеспечить реализацию в базовом классе. Однако производный класс может переопределить эту реализацию своей собственной реализацией. Обычно для чистых виртуальных функций реализация не предусмотрена. Вы можете сделать функцию чистой виртуальной с =0 в конце объявления функции. Кроме того, класс, содержащий чистую виртуальную функцию, является абстрактным, т.е. Вы не можете создать объект этого класса.

Ответ 3

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

Вы обозначаете этот факт, добавляя к объявлению "= 0", например:

class AbstractBase
{
    virtual void PureVirtualFunction() = 0;
}

Тогда вы не можете объявлять и создавать экземпляр подкласса без реализации чистой виртуальной функции:

class Derived : public AbstractBase
{
    virtual void PureVirtualFunction() override { }
}

Добавив ключевое слово override, компилятор будет гарантировать, что существует виртуальная функция базового класса с той же сигнатурой.