DEV Community

C++, Static Object - Singleton pattern

dinhluanbmt on June 29, 2023

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 ...
Collapse
 
pgradot profile image
Pierre Gradot • Edited

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.

Collapse
 
dinhluanbmt profile image
dinhluanbmt

thank you, i forgot to make private Copy constructor and assignment operator .
i will update my post.

Singleton has been considered as an anti-pattern for a long time now... Why still writing blog post about it?
I agree that, but my works (Applications for Car) now still deal with many Singleton

Collapse
 
pgradot profile image
Pierre Gradot • Edited

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 a Screen& as parameters to functions that needs a Screen object to display stuff.

Thread Thread
 
dinhluanbmt profile image
dinhluanbmt

thank you, i got it^^

Collapse
 
pauljlucas profile image
Paul J. Lucas

There's no reason to use shared_ptr. Ordinary pointers are just fine.

Collapse
 
dinhluanbmt profile image
dinhluanbmt

right, but i just don't want to handle the deallocation work

Collapse
 
pauljlucas profile image
Paul J. Lucas

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.

Thread Thread
 
dinhluanbmt profile image
dinhluanbmt • Edited

really, could you tell me more ? with ordinary pointer the code above never call my Destructor ?

Thread Thread
 
pauljlucas profile image
Paul J. Lucas
class S {
    S() { }
public:
    static S* instance();
};

S* S::instance() {
    static S instance_obj;
    return &instance_obj;
}
Enter fullscreen mode Exit fullscreen mode

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:

S* S::instance() {
    static S *const instance_obj = new S{};
    return instance_obj;
}
Enter fullscreen mode Exit fullscreen mode

In this case, the destructor will never be called, but you avoid the fiasco. There's no perfect answer.

Thread Thread
 
dinhluanbmt profile image
dinhluanbmt

nice ! i got it

Thread Thread
 
pauljlucas profile image
Paul J. Lucas