Обеспечить чистый виртуальный деструктор:
struct Base {
virtual ~Base() = 0;
};
inline Base::~Base() {}
Вам нужно обеспечить реализацию, которые вы могли бы прямо в заголовке, сделав его inline
.
Абстрактный класс является классом с некоторой чистой виртуальной функции:
[...] Класс является абстрактным, если он имеет по крайней мере одну чистую виртуальную функцию. [...]
[N4431 §10.4/2]
Поскольку вы хотите массив указателей на экземпляры классов (полученных от) Ваш абстрактный класс, я полагаю, вы также хотите, чтобы иметь возможность в конце концов, и, таким образом delete
деструктора один или несколько из этих случаев с помощью этих указателей:
Base * instance = // ... whatever ...
delete instance;
для вызова правильного деструктора (производный класса) в этом случае деструктор имеет быть виртуальными.
Так как это виртуально в любом случае, и вам не нужна какая-то чистая виртуальная функция-член, лучше всего сделать деструктор чистым виртуальным.
Чтобы сделать виртуальную функцию чистой, вы добавите чисто-спецификатор в своей декларации:
struct Foo {
virtual void bar(void) /* the */ = 0; // pure-specifier
};
Теперь, что касается определения, вы удивляетесь, почему мы должны обеспечить один, так как ...
[...] Чистая виртуальная функция должна быть определена только при вызове с или, как если бы с (12.4), синтаксисом квалифицированного идентификатора (5.1). [...]
[N4431 §10.4/2]
Это потому, что, когда разрушающее производный класс, после того, как производные классы деструктор был вызван, также будут называть деструкторы классов оснований:
struct Derived : public Base {
~Derived() {
// contents
// Base::~Base() will be called
}
};
После выполнения тела деструктора [...] деструктор для класса X вызовов [...] деструкторы для классов прямых базовых иксов и, если X является типом наиболее производным класса (12,6 .2), его деструктор вызывает деструкторы для виртуса X базовых классов. Все деструкторы вызываются, как если бы они были ссылки с составным именем [...]
[N4431 §12.4/8]
Так определение чистого виртуального деструктора, если Base
класс необходим. Однако ...
[...] Объявление функции не может обеспечить как чисто-спецификатор и определение [...]
[N4431 §10.4/2]
... поэтому он должен быть определен вне определения класса. Это может быть сделано в отдельном исходном файле, или благодаря ...
Инлайн функция должна быть определена в каждом единице трансляции, в которой он ODR используются и должны иметь точно такое же определение в каждом конкретном случае [ ...]
[N4431 §7.1.2/4]
... как inline
функции в заголовке.
Стандарт даже явный о требовании определения в этом случае:
Деструктор может быть объявлен виртуальным (10.3) или чисто виртуальным (10.4); если в программе создаются какие-либо объекты этого класса или любого производного класса, деструктор должен быть определен. [...]
[N4431 §12.4/9]
содержит ли переменные-члены? –
Каким будет использование такой вещи? Это базовый класс, но в нем ничего нет? – Barry
@Barry Разве вы не читали вопрос? '(Полезно для« многих вещей »...)';) – fredoverflow