For many reasons, we may want only one instance of a class to exist throughout the lifetime of an application. This is where the Singleton pattern comes
class mSingleObj {
private:
static shared_ptr<mSingleObj> instance;
string description = "this is single instance object";
// private constructor so that we can not create an instance
mSingleObj(){}
// private copy constructor and assignment operator
// previous version of c++
mSingleObj(const mSingleObj&){}
mSingleObj& operator=(const mSingleObj&) {}
// move constructor and move assignment operator
// >= c++11 we can delete
mSingleObj(mSingleObj&& ) = delete;
mSingleObj& operator=(mSingleObj&& ) = delete;
public:
//the only one way to to get object
static shared_ptr<mSingleObj> getInstance() {
return instance;
}
void display() {
cout << description << endl;
}
~mSingleObj() { cout << "Destructor called only one..." << endl; }
};
//static object need to be initialized outside the class defination
shared_ptr<mSingleObj> mSingleObj::instance(new mSingleObj());
void testSingletonObj() {
shared_ptr<mSingleObj> sObj = mSingleObj::getInstance();
sObj->display();
shared_ptr<mSingleObj> other_sObj = mSingleObj::getInstance();
other_sObj->display();
//check whether objects are the same
cout << "(sObj) Address of managed object: " << sObj.get() << std::endl;
cout << "(other_sObj) Address of managed object: " << other_sObj.get() << std::endl;
}
Important things:
- the private constructor
- a way to get the object (because we cant not create an object of class with private constructor)
- the private Copy constructor and Copy assignment operator
But in my experience, I really dislike the Singleton pattern when dealing with unit tests.
Top comments (11)
Singleton has been considered as an anti-pattern for a long time now... Why still writing blog post about it?
Especially to show a errorneous implementation... Simply add
mSingleObj copy = *sObj;
to your test function and now you have two instances 😮Implementing this pattern in C++ is quite tricky. See modernescpp.com/index.php/creation... (especially "The Meyers Singleton") for a robust implementation.
thank you, i forgot to make private Copy constructor and assignment operator .
i will update my post.
Maybe you should use C++11's features and delete them, instead of making them private. You can also default the constructor.
Even with these modifications, you implementation still have flaws (see the link).
I know many people still deal with singletons especially in legacy code. More than often, singletons are used as a convenience to get an instance of an object. Like
Screen::getInstance()
, instead of passing aScreen&
as parameters to functions that needs aScreen
object to display stuff.thank you, i got it^^
There's no reason to use
shared_ptr
. Ordinary pointers are just fine.right, but i just don't want to handle the deallocation work
Who says you have to deallocate it? You return a pointer to a function local static object. It will be destroyed when the program terminates.
really, could you tell me more ? with ordinary pointer the code above never call my Destructor ?
Again, the destructor will be called upon program termination. However, that can cause the destruction order fiasco in some cases (where the destructor will be called while some other code in some other translation unit is still using it). A solution that avoids that is:
In this case, the destructor will never be called, but you avoid the fiasco. There's no perfect answer.
nice ! i got it
I wrote my own blog post about singletons.