2
class MyClassPrivate
{
//My members.
};    

//and then
class MyClass {
private:
 MyClassPrivate* const d;
};

What is the reason of using this 'pattern'? How it's correctly called?

Yevhen
  • 1,727
  • 2
  • 13
  • 25

3 Answers3

4

This is called "Pointer to implementation" or "pimpl". See http://en.wikibooks.org/wiki/C++_Programming/Idioms#Pointer_To_Implementation_.28pImpl.29

When you use this pattern you would forward declare the implementation class, and declare the body elsewhere, i.e.:

// header
class MyClassPrivate;
class MyClass {
public:
  MyClass();
  ~MyClass();
private:
  MyClassPrivate* const d;
};

// cpp
class MyClassPrivate {
};
MyClass::MyClass() : d(new MyClassPrivate) {}
MyClass::~MyClass() { delete d; }

The advantage of doing this is that the implementation of MyClass is not exposed to other users of MyClass. If the implementation changes, the other users of MyClass does not need to be recompiled. Any header files that has to be included for members also need not be exposed, which improves compilation time.

yiding
  • 3,243
  • 14
  • 17
3

The most usage is Pimlp idiom.

The Pimpl idiom describes a way for making your header files impervious to change. You often hear advices like "Avoid change your public interface!" So you can modify your private interface, but how can you avoid recompilation when your header file defines the private methods. This is what the Pimpl does – Reduce compilation damages when your private interface changes[3].

From Here:

Benefits:

  1. Changing private member variables of a class does not require recompiling classes that depend on it, thus make times are faster, and the FragileBinaryInterfaceProblem is reduced.
  2. The header file does not need to #include classes that are used 'by value' in private member variables, thus compile times are faster.
  3. This is sorta like the way SmallTalk automatically handles classes... more pure encapsulation.

Drawbacks:

  1. More work for the implementer.
  2. Doesn't work for 'protected' members where access by subclasses is required.
  3. Somewhat harder to read code, since some information is no longer in the header file.
  4. Run-time performance is slightly compromised due to the pointer indirection, especially if function calls are virtual (branch prediction for indirect branches is generally poor).

How to do it:

  1. Put all the private member variables into a struct.
  2. Put the struct definition in the .cpp file.
  3. In the header file, put only the ForwardDeclaration of the struct.
  4. In the class definition, declare a (smart) pointer to the struct as the only private member variable.
  5. The constructors for the class need to create the struct.
  6. The destructor of the class needs to destroy the struct (possibly implicitly due to use of a smart pointer).
  7. The assignment operator and CopyConstructor need to copy the struct appropriately or else be disabled.
Community
  • 1
  • 1
masoud
  • 51,434
  • 14
  • 119
  • 190
1

You can use this for the PIMPL idiom, when you want to separate interface from iplementation.

Many design patterns use a "pointer" to a private attribute as well, such as the Strategy Pattern. This patterns allows you to select a different algorithm at run-time.

Also, if you make the manipulation of your data adhere to the same interface, you can encapsulate the data in a Private Class, make this class a part of a hierarchy and switch between different data implementations during run time (or compile time for that matter :)).

A good example of this is a geometrical class that holds data on polygons. Each Polygon provides access to the points, you can also delete the Polygon edge and do various other topological operations. If you provide an abstract base class for the Polygon class with the methods such as deletePoint, addPoint, swapEdge, you can test different Polygon implementations.

You may define a polygon as a list of Point types directly, and store the points in different contaienrs (list or vector). The Polygon class may be defined via indirect addressing, where the polygon is actually a list of IDs to the list of points (I am talking about lists in the general sense). This way, you can test different algorithms of the PolygonGeometry class and see how they work with differtn Polygon implementations.

There is a design principle behind this: Prefer Composition to Inheritance. Whenever you are using Composition and you are relying on the type to be deterimined at run-time, you will have a private attribute pointer.

tmaric
  • 4,835
  • 3
  • 33
  • 65