20

While looking over some code, I ran into the following:

.h file

class ExampleClass
{
public:
    // methods, etc
private:
    class AnotherExampleClass* ptrToClass;
}

.cpp file

class AnotherExampleClass
{
    // methods, etc
}

// AnotherExampleClass and ExampleClass implemented 

Is this a pattern or something beneficial when working in c++? Since the class is not broken out into another file, does this work flow promote faster compilation times?

or is this just the style this developer?

afuzzyllama
  • 6,275
  • 5
  • 42
  • 61

3 Answers3

25

This is variously known as the pImpl Idiom, Cheshire cat technique, or Compilation firewall.

Benefits:

  • 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.
  • The header file does not need to #include classes that are used 'by value' in private member variables, thus compile times are faster.
  • This is sorta like the way SmallTalk automatically handles classes... more pure encapsulation.

Drawbacks:

  • More work for the implementor.
  • Doesn't work for 'protected' members where access by subclasses is required.
  • Somewhat harder to read code, since some information is no longer in the header file.
  • 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).

Herb Sutter's "Exceptional C++" books also go into useful detail on the appropriate usage of this technique.

bgporter
  • 30,774
  • 8
  • 54
  • 62
11

The most common example would be when using the PIMPL pattern or similar techniques. Still, there are other uses as well. Typically, the distinction .hpp/.cpp in C++ is rather (or, at least can be) one of public interface versus private implementation. If a type is only used as part of the implementation, then that's a good reason not to export it in the header file.

Ulrich Eckhardt
  • 15,392
  • 1
  • 25
  • 49
7

Apart from possibly being an implementation of the PIMPL idiom, here are two more possible reason to do this:

Objects in C++ cannot modify their this pointer. As a consequence, they cannot change type in mid-usage. However, ptrToClass can change, allowing an implementation to delete itself and to replace itself with another instance of another subclass of AnotherExampleClass.

If the implementation of AnotherExampleClass depends on some template parameters, but the interface of ExampleClass does not, it is possible to use a template derived from AnotherExampleClass to provide the implementation. This hides part of the necessary, yet internal type information from the user of the interface class.

cmaster - reinstate monica
  • 33,875
  • 7
  • 50
  • 100