У меня есть очень простая реализация отражения, которая включает класс Type
, который создает экземпляр объекта для описываемого класса. Лишенный вплоть до соответствующих частей, то она выглядит следующим образом:Является ли пользовательским удалением для std :: unique_ptr допустимым местом для ручного вызова деструктора?
Type.h:
class Plugin; // forward declaration
typedef std::unique_ptr<Plugin> PluginPtr;
namespace Reflection {
class Type {
public:
explicit Type(PluginPtr(*)());
PluginPtr CreateInstance();
private:
PluginPtr(*_createInstance_Handler)();
};
}
Type.cpp:
Type::Type(PluginPtr(*createInstance_Handler)()) :
_createInstance_Handler(createInstance_Handler) {}
PluginPtr CreateInstance() { return (*_createInstance_Handler)(); }
Фактическая логика конкретизации расположен в Plugin
классе (и Кроме того, в каждом из его потомков):
Plugin.h:
class Plugin {
public:
virtual ~Plugin();
static const Reflection::Type Type;
private:
static PluginPtr CreateInstance();
plugin.cpp
Plugin::~Plugin() {}
const Reflection::Type Plugin::Type(CreateInstance);
PluginPtr Plugin::CreateInstance() { return PluginPtr(new Plugin); }
Когда я пытаюсь скомпилировать это я получаю эти ошибки (в Visual Studio 2013):
error C2027: use of undefined type 'Plugin'
error C2338: can't delete an incomplete type
warning C4150: deletion of pointer to incomplete type 'Plugin'; no destructor called
я выкопал вокруг немного, и по-видимому, это вызвано удалением std :: unique_ptr (находящимся внутри определения класса класса, на котором он работает). Я где-то читал, что если я поставлю свой собственный делеттер, эта проблема исчезнет. Поэтому я пересмотрел PluginPtr
к этому:
typedef std::unique_ptr<Plugin, PluginDeleter> PluginPtr
The (сборник) проблема действительно уходит, но вопрос тогда, может/должен это PluginDeleter
вызова ~Plugin()
вручную (для того, чтобы плагин (и любой полученный объект плагинPtr может указывать на!) правильно разрушен)? И где/как лучше всего объявить/определить его, чтобы у меня не возникала проблема с неполными типами?
(или есть лучший способ вообще?)
PS. Работая над своим исходным кодом, я понимаю, что в приведенном выше коде есть ошибка. Последняя строка в Type.cpp следует читать
PluginPtr CreateInstance() { return (_createInstance_Handler)(); }
'использование неопределенного типа 'Плагин'': вы пытались использовать полный тип раньше? т. е. объявить весь класс, прежде чем использовать его unique_ptr? – Geoffroy
@ Geoffroy: да. – d7samurai
Вы используете 'delete' в своем PluginDeleter? – Geoffroy