Имеет ли смысл определять "чистые" виртуальные функции в базовом классе?

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

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

#include <iostream>
using namespace std;

class speciesFamily
{
    public:
        virtual void numberOfLegs () = 0;
};

void speciesFamily :: numberOfLegs ()
{
    cout << "\nFour";
}

class catFamily : public speciesFamily
{
    public:
        void numberOfLegs ()
        {
            speciesFamily :: numberOfLegs ();
        }
};

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

Ответ 1

Есть ли ситуации, когда полезно определить чистую виртуальную функцию в базовом классе?

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

Ответ 2

Две вещи:

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

struct EmptyAbstract
{
  virtual ~EmptyAbstract() = 0; // force class to be abstract
};
EmptyAbstract::~EmptyAbstract() { } // but still make d'tor callable

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

Во-вторых, вы всегда можете вызывать функции базового класса из производных классов, поэтому вы можете просто хотеть иметь "общий" набор функций, несмотря на то, что не хотите каких-либо абстрактных экземпляров. Опять же, приходят чисто виртуальные определенные функции:

struct Base
{
  virtual void foo() = 0;
};

struct Derived : Base
{
  virtual void foo()
  {
    Base::foo();  // call common features
    // do other stuff
  }
};

void Base::foo() { /* common features here */ }

Ответ 3

Базовый класс с только чистыми виртуальными функциями - это такие языки, как Java, которые будут вызывать интерфейс. Он просто описывает, какие функции доступны, ничего больше.

Ответ 4

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