mercredi 6 mai 2015

std::unique_ptr for class data member ABI (Pimpl idiom)

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)?

Aucun commentaire:

Enregistrer un commentaire