c++ singleton implementation : pimpl idiom for singletons, pros and cons
When implementing singletons in c++, I see two ways to store implementation data :
(A) put all implementation data in the private section and implement class as usual
(B) "pimpl idiom for singletons" : hide implementation data by placing it to the 'Impl' structure, which can be defined in the implementation file. Private section contains only a reference to the implementation structure.Here is a concept code to clarify what I mean by (A) and (B) implementation options :
(A) SingletonClassMembers.hpp :
// a lot of includes required by private section
#include "HelperClass1.hpp"
#include "HelperClass2.hpp"
// some includes required by public section
// ...
class SingletonClassMembers {
public:
static SingletonClassMembers& getInstance();
// public methods
private:
SingletonClassMembers ();
~SingletonClassMembers();
SingletonClassMembers (const SingletonClassMembers&); //not implemented
SingletonClassMembers& operator=(const SingletonClassMembers&); //not implemented
HelperClass1 mMember1;
HelperClass2 mMember2; //and so on
(A) SingletonClassMembers.cpp :
#include "SingletonClassMembers.hpp"
SingletonClassMembers& getInstance() {
static SingletonClassMembers sImpl;
return sImpl;
}
(B) SingletonHiddenImpl.hpp :
// some includes required by public section
// ...
class SingletonHiddenImpl {
public:
static SingletonHiddenImpl& getInstance();
// public methods
private:
SingletonHiddenImpl ();
~SingletonHiddenImpl ();
SingletonHiddenImpl (const SingletonHiddenImpl&); //not implemented
SingletonHiddenImpl& operator=(const SingletonHiddenImpl&); //not implemented
struct Impl;
Impl& mImpl;
};
(B) SingletonHiddenImpl.cpp :
#include "SingletonHiddenIm开发者_Python百科pl.hpp"
#include "HelperClass1.hpp"
#include "HelperClass2.hpp"
struct SingletonHiddenImpl::Impl {
HelperClass1 member1;
HelperClass2 member2;
};
static inline SingletonHiddenImpl::Impl& getImpl () {
static Impl sImpl;
return sImpl;
}
SingletonHiddenImpl::SingletonHiddenImpl ()
: mImpl (getImpl())
{
}
So, using (B) approach, you can hide implementation details better and (unlike pimpl idiom for ordinary classes) there`s no performance loss. I can`t imagine conditions where (A) approach would be more appropriate
The question is, what are the advantages of storing implementation data as class members (A) ?
Thank you
Using case A has following benefits:
- You reduce dependency between classes SingletonClassMembers and SingletonHiddenImpl.
- You don't need to create configurator pattern in class SingletonClassMembers if you trying avoid restriction on (1) by dependency injection
- This case is weak, but anyway: it is simple to maintenance single class
- In multithreading environment you will need to support both class synchronization mechanism, while in single class only single locks is needed.
As you only have one instance of your singleton, you can actually move your helpers into the implementation class as "static" there without requiring them to be private inside the header. Of course you don't want to initialise them until you start your class so you would use some kind of smart-pointer, could be auto_ptr here or boost::scoped_ptr, or a pointer with boost::once initialisation (more thread-safe) with deletes in your singleton's destructor.
You can call this model C and probably has the best of both worlds as you completely hide your implementation.
As is the case with any singleton, you need to be extra careful not to throw in your constructor.
When considering efficiency with pimpl, it is not the heap that causes overhead, but the indirection (done by delegation). This delegation typically isn't optimized out (at least not at the time I was considering this ;-)), so there is not a big gain apart from the startup (1 time) penalty for creating the impl. (BTW, I didn't see any delegation functions in your example)
So I don't see that much difference in using pimpl in normal classes or in singletons. I think in both case, using pimpl for classes with limited interface and heavy implementation, it makes sense.
精彩评论