Ответ 1
Есть ли ситуации, когда полезно определить чистую виртуальную функцию в базовом классе?
Да - если рассматриваемая функция является чистым виртуальным деструктором, она также должна быть определена базовым классом.
Преимущество определения обычных виртуальных функций в базовом классе состоит в том, что тогда нам не нужно переопределять их в производных классах.
Даже если мы определяем виртуальные функции чистые в базовом классе, нам все равно придется определять их и в производных классах.
#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 ();
}
};
Это может показаться странным, но есть ли ситуации, когда полезно определять чистую виртуальную функцию в базовом классе?
Есть ли ситуации, когда полезно определить чистую виртуальную функцию в базовом классе?
Да - если рассматриваемая функция является чистым виртуальным деструктором, она также должна быть определена базовым классом.
Две вещи:
Во-первых, существует один сценарий пограничной линии, который обычно цитируется: предположим, что вы хотите использовать абстрактный базовый класс, но у вас нет виртуальных функций для его ввода. Это означает, что у вас нет функций для создания чисто виртуальных. Теперь один путь: поскольку вам всегда нужен виртуальный деструктор, вы можете сделать это чистым. Но вам также нужна реализация, чтобы ваш кандидат:
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 */ }
Базовый класс с только чистыми виртуальными функциями - это такие языки, как Java, которые будут вызывать интерфейс. Он просто описывает, какие функции доступны, ничего больше.
Это может быть полезно, когда разумная реализация чистой виртуальной функции не может быть в базовом классе. В этом случае чистые виртуальные функции реализуются в производных классах.