I'm trying to define existing code that use "pimpl" data members to be defined with unique_ptr. Some objects requires a custom deleter, and others not.
unique_ptr (unlike shared_ptr) destructor requires knowing a complete type of the object. So you need to specify the deleter in the data member declaration:
class Foo {
public:
...
~Foo (void) //in source file =default
private:
class FooImpl;
std::unique_ptr <FooImpl> _pimpl;
};
When instantiating the pimpl you are constrained to using the default deleter. If you want a custom deleter, you need to specify it in the declaration
class Foo {
public:
...
~Foo (void) //in source file =default
private:
class FooImpl;
std::unique_ptr <FooImpl, std::function <void (FooImpl*&)> > _pimpl;
};
However, you can't have the option to be flexible whether you want the unique_ptr d'tor with default behaviour or a custom deleter. The more flexible option is the second version, but if you choose to keep with the default behaviour, then you must instantiate the unique_ptr with a specific deleter that is equivalent to the default delete, such as:
Foo::Foo (void) :
_impl (new CurveItemWidgetImpl, std::default_delete <FooImpl> ()) {
}
So, is std::unique_ptr the best way to handle ABI (compared to shared_ptr or raw pointer)?