Search code examples
c++inner-classespimpl-idiomopaque-pointers

When to use Pimpl pattern over Nested class in C++ or vice versa?


In C++ ,most of developers are using pimpl idiom or opaque pointers to hide the private data/implementation from the public API, for an example :

  1. => first case ## Opaque Pointer and PIMPL idiom ##

// in header file

class Node; 
class Graph {  
 public:    
  A();  
 private:  
  Node* m_nodeImpl; 
}

// class Node will be defined in respective cpp

2. => second case ## Inner class / Nested class approach ##

// in header file

class Graph {  
 public:    
  Graph(){};  
 private:  
  class Node
  {
    // implementation goes here
  }
  Node* m_nodeImpl;
}

Question is ...

  1. What is the actual difference between these two approached in perspective of class design (design patterns may be)?
  2. What are the advantages and disadvantages on each over each?

Solution

  • You're mixing up several things:

    1. first example

      1. Type: opaque - that means the type name is visible to users of this header, but the definition is hidden.

        Opaque types are particularly useful when you want to share a pointer with your users, but not the details of what it points to (either to discourage users from fiddling with it, or to break up dependencies).

      2. Storage: pimpl. This just means the users know you (may) have an instance of the opaque type somewhere, and they know the size of your top-level object includes that pointer.

    2. second example

      1. Type: nested - this avoids polluting the enclosing namespace (so there can be other types of Node in the same namespace in your program, unlike the first example) but exposes all the details.

        Note that your nested type could also be forward-declared, to control both visibility and namespace pollution.

      2. Storage: missing. Did you mean to have a Node *m_impl here too? Otherwise the examples aren't directly comparable, as there's nowhere for your Graph to keep a Node, however the type is declared.