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?
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:
Impl
for all pImpl classesHiddenStuff_A*
or ``HiddenStuff_B&type, but unless
g_visibleprovides a factory or
HiddenStuff_X`'s definition's included in the translation unit it can't actually get variables to point at or call withIn short, not having the
Impl
declarationsprivate
is a poor choice.