Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Private members in pimpl class?

Is there any reason for the implementation class as used in the pimpl idiom to have any private members at all? The only reason I can really think of is to protect yourself from yourself -- i.e. the private members serve to enforce some kind of contract between the class and the user, and in this case the class and the user are rather intimately related, so it seems unnecessary.

like image 943
Anne Avatar asked Feb 01 '10 16:02

Anne


4 Answers

I think people are confusing the Pimpl idiom with Adapter/Bridge/Strategy patterns. Idioms are specific to a language. Patterns can apply to many languages.

The Pimpl idiom was devised to address the following problem in C++: Private members of a class are visible in the class declaration, which adds unnecessary #include dependencies to the user of the class. This idiom is also known as compiler firewall.

If the implementation is written directly in the outer class's corresponding *.cpp file, and is not accessible outside the module, then I think its perfectly fine to simply use a struct for the Pimpl class. To further re-enforce the idea that implementations are not meant to be directly re-used, I define them as a private inner struct:

// foo.h
class Foo : boost::noncopyable
{
public:
   ...

private:
   struct Impl;
   boost::scoped_ptr<Impl> impl_;
};

// foo.cpp
struct Foo::Impl
{
   // Impl method and member definitions
};

// Foo method definitions

As soon as there's a header file for the implementation class, I think we are no longer talking about the Pimpl idiom. We are rather talking about Adapter, Bridge, Strategy, interface classes, etc...

Just my 2 cents.

like image 74
Emile Cormier Avatar answered Nov 10 '22 01:11

Emile Cormier


Depends on your implementation of pImpl - specifically where you enforce the class invariant, but in general I see no need for the impl part to have protected/private members. In fact, I usually declare it as a struct.

like image 31
Nemanja Trifunovic Avatar answered Nov 10 '22 00:11

Nemanja Trifunovic


In theory a pimpl class is still just a class like any other. That it is a concrete implementation of an interface doesn't mean that other code isn't a client of the pimpl class itself.

That said, in practice I have found that pimpl classes tend to be much closer to structs with some member functions rather than full fledged objects, and have less need to separate the interface from the implementation.

like image 28
John Dibling Avatar answered Nov 10 '22 01:11

John Dibling


Why shouldn't it have private members? Just because you're defining one interface as PIMPL doesn't mean that you will at no other time want to use the class.

It's still a class. Data should probably be private or protected. Operations on data that will never be accessible to the public, private or protected. Operations that you might wish to expose, protected, or public.

like image 28
Liz Albin Avatar answered Nov 10 '22 01:11

Liz Albin