Difference between global vs private forward declarations in pimpl for the end user of the pimpl

228 views Asked by At

Consider the following two ways of implementing the pimpl idiom:

// file  g_visible.h 

//global forward declarations
class HiddenStuff_A;
class HiddenStuff_B;

class g_visible
{
   public:

      // API goodies for the end-user

   private:
      std::unique_ptr< HiddenStuff_A >  hs_a;
      std::unique_ptr< HiddenStuff_B >  hs_b;
}

and

// file  p_visible.h 

class p_visible
{
   public:

      // API goodies for the end-user

   private:
      // private forward declarations
      class HiddenStuff_A;
      class HiddenStuff_B;
      std::unique_ptr< HiddenStuff_A >  hs_a;
      std::unique_ptr< HiddenStuff_B >  hs_b;
}

Question: For the end-user -- i.e., for the developer who would include one of the [gp]_visible.h files -- what would be difference between including g_visible.h or p_visible.h?

1

There are 1 answers

0
Tony Delroy On

The difference is that they have forward declarations of the two "Hidden" classes in global scope (or if your code put g_visible in a namespace, then whatever namespace that happened to be).

Unnecessary namespace pollution. The practical consequences:

  • they can't use the same identifier again in that namespace, whereas I tend to use Impl for all pImpl classes
  • their IDE's completion list wastes space on identifiers they'll never want to pick.
  • client code could do things like define variables or function arguments of HiddenStuff_A* or ``HiddenStuff_B&type, but unlessg_visibleprovides a factory orHiddenStuff_X`'s definition's included in the translation unit it can't actually get variables to point at or call with

In short, not having the Impl declarations private is a poor choice.