Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pros and Cons of usage of reference in case of PIMPL idiom

As mentioned here you can use reference (d-reference) instead of pointer (d-pointer) in case of PIMPL idiom.

I'm trying to understand if there are any serious issues with this implementation and what are the pros and cons.

Pros:

  • Shorter syntax because of usage of "." instead of "->".
  • ...

Cons:

  • What if the new ObjectPivate() fails and new doesn't throw (e.g.: new(std::nothrow) or custom new) and returns nullptr instead? You need to implement additional stuff to check if the referance is valid. In case of pointer you just use:

if (m_Private)
  m_Private->Foo();

  • In rare case of multiple constructors for the Object with complex initialisation logic the solution could be not applicable. [© JamesKanze]
  • It fills more natural to use pointer for memory management. [© JamesKanze]
  • Some additional implementation details needs to be considered (use of swap()) to ensure the exception-safety (e.g. implementation of assignment operator) [© Matt Yang]
  • ...

Here the sample code for illustration:

// Header file

class ObjectPrivate;

class Object
{
public:
 Object();
 virtual ~Object();

 virtual void Foo();

 private:
   ObjectPrivate&  m_Private;
};

// Cpp file

class ObjectPrivate
{
public:
  void Boo() { std::cout << "boo" << std::endl; }
};

Object::Object() :
m_Private(* new ObjectPrivate())
{
}

Object::~Object()
{
  delete &m_Private;
}

void Object::Foo()
{
  m_Private.Boo();
}
like image 854
mem64k Avatar asked Feb 16 '23 20:02

mem64k


1 Answers

It's really just a matter of style. I tend to not use references in classes to begin with, so using a pointer in the compilation firewall just seems more natural. But there's usually no real advantage one way or the other: the new can only fail by means of an exception.

The one case where you might favor the pointer is when the object has a lot of different constructors, some of which need preliminary calculations before calling the new. In this case, you can initialize the pointer with NULL, and then call a common initialization routine. I think such cases are rare, however. (I've encountered it once, that I can recall.)

EDIT:

Just another style consideration: a lot of people don't like something like delete &something;, which is needed if you use references rather than pointers. Again, it just seems more natural (to me, at least), that objects managing memory use pointers.

like image 180
James Kanze Avatar answered Feb 19 '23 09:02

James Kanze