I have a very basic implementation of reflection that includes a Type
class which does object instantiation for the class it describes. Stripped down to the relevant parts, it looks like this:
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)(); }
The actual instantiation logic is housed in the Plugin
class (and also in each of its descendants):
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); }
When I attempt to compile this, I get these errors (in 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
I dug around a bit, and apparently this is caused by the deleter of the std::unique_ptr (finding itself inside the class definition of the class it is operating on). I read somewhere that if I supply my own deleter, this problem goes away. So I redefined PluginPtr
to this:
typedef std::unique_ptr<Plugin, PluginDeleter> PluginPtr
The (compilation) problem does indeed go away, but the question then, is can/should this PluginDeleter
call ~Plugin()
manually (to ensure that the plugin (and any derived object that the PluginPtr might be pointing to!) is properly destructed)? And where/how should I best declare/define it, so that I don't get the same problem with incomplete types?
(or is there a better way altogether?)
PS. Working on my source code now, I realize that there's an error in the above code. The last line in Type.cpp should read
PluginPtr CreateInstance() { return (_createInstance_Handler)(); }