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