Предоставьте чистый виртуальный деструктор:
struct Base {
virtual ~Base() = 0;
};
inline Base::~Base() {}
Вам нужно предоставить реализацию, которую вы можете прямо в заголовке сделать inline
.
Абстрактный класс - это класс с некоторой чистой виртуальной функцией:
[...] Класс является абстрактным, если он имеет хотя бы одну чистую виртуальную функцию. [...]
[N4431 §10.4/2]
Поскольку вам нужен массив указателей на экземпляры (классы, производные от) вашего абстрактного класса, я предполагаю, что вы также хотите иметь возможность в конечном итоге delete
и, таким образом, уничтожить один или несколько из этих экземпляров с помощью этих указателей:
Base * instance = // ... whatever ...
delete instance;
Чтобы вызвать правильный деструктор (производного класса) в этом случае, деструктор должен быть виртуальным.
Итак, поскольку он в любом случае виртуальный, и вам не нужна какая-то чисто виртуальная функция-член, лучше всего сделать деструктор чисто виртуальным.
Чтобы сделать виртуальную функцию чистой, вы добавляете к ее объявлению pure-specier:
struct Foo {
virtual void bar(void) /* the */ = 0; // pure-specifier
};
Теперь, что касается определения, вы задаетесь вопросом, зачем нам его давать, поскольку ...
[...] Чистая виртуальная функция должна быть определена только в том случае, если она вызывается с синтаксисом квалифицированного идентификатора (5.1) или как если бы с (12.4). [...]
[N4431 §10.4/2]
Это связано с тем, что при деструкции производного класса после вызова деструктора производных классов также будут вызываться деструкторы базовых классов:
struct Derived : public Base {
~Derived() {
// contents
// Base::~Base() will be called
}
};
После выполнения тела деструктора [...] деструктор для класса X вызывает [...] деструкторы для прямых базовых классов 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]
person
Daniel Jour
schedule
03.08.2015
(Useful for 'many things'...)
;) - person fredoverflow   schedule 03.08.2015