Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

dinhluanbmt
dinhluanbmt

Posted on • Edited on

C++, Static Object - Singleton pattern

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

classmSingleObj{private:staticshared_ptr<mSingleObj>instance;stringdescription="this is single instance object";// private constructor so that we can not create an instancemSingleObj(){}// private copy constructor and assignment operator//  previous version of c++mSingleObj(constmSingleObj&){}mSingleObj&operator=(constmSingleObj&){}// move constructor and move assignment operator// >= c++11 we can deletemSingleObj(mSingleObj&&)=delete;mSingleObj&operator=(mSingleObj&&)=delete;public://the only one way to to get objectstaticshared_ptr<mSingleObj>getInstance(){returninstance;}voiddisplay(){cout<<description<<endl;}~mSingleObj(){cout<<"Destructor called only one..."<<endl;}};//static object need to be initialized outside the class definationshared_ptr<mSingleObj>mSingleObj::instance(newmSingleObj());voidtestSingletonObj(){shared_ptr<mSingleObj>sObj=mSingleObj::getInstance();sObj->display();shared_ptr<mSingleObj>other_sObj=mSingleObj::getInstance();other_sObj->display();//check whether objects are the samecout<<"(sObj) Address of managed object: "<<sObj.get()<<std::endl;cout<<"(other_sObj) Address of managed object: "<<other_sObj.get()<<std::endl;}
Enter fullscreen modeExit fullscreen mode

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)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
pgradot profile image
Pierre Gradot
Committed defender of C++ / Learning Rust / Python & CMake lover / Black metal guitarist & mountain bike rider
  • Location
    Nantes, France
  • Work
    Software System Engineer at eShard
  • Joined
• Edited on• 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 addmSingleObj copy = *sObj; to your test function and now you have two instances 😮

Implementing this pattern in C++ is quite tricky. Seemodernescpp.com/index.php/creation... (especially "The Meyers Singleton") for a robust implementation.

CollapseExpand
 
dinhluanbmt profile image
dinhluanbmt
I just wrote some notes based on my experience about C++. I hope this helps.
  • Education
    Chosun University, South Korea
  • Work
    Software Engineer
  • Joined

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

CollapseExpand
 
pgradot profile image
Pierre Gradot
Committed defender of C++ / Learning Rust / Python & CMake lover / Black metal guitarist & mountain bike rider
  • Location
    Nantes, France
  • Work
    Software System Engineer at eShard
  • Joined
• Edited on• 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. LikeScreen::getInstance(), instead of passing aScreen& as parameters to functions that needs aScreen object to display stuff.

Thread Thread
 
dinhluanbmt profile image
dinhluanbmt
I just wrote some notes based on my experience about C++. I hope this helps.
  • Education
    Chosun University, South Korea
  • Work
    Software Engineer
  • Joined

thank you, i got it^^

CollapseExpand
 
pauljlucas profile image
Paul J. Lucas
C++ Jedi Master
  • Email
  • Location
    San Francisco Bay Area
  • Education
    University of Illinois at Urbana-Champaign
  • Work
    Retired Principal Software Engineer
  • Joined

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

CollapseExpand
 
dinhluanbmt profile image
dinhluanbmt
I just wrote some notes based on my experience about C++. I hope this helps.
  • Education
    Chosun University, South Korea
  • Work
    Software Engineer
  • Joined

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

CollapseExpand
 
pauljlucas profile image
Paul J. Lucas
C++ Jedi Master
  • Email
  • Location
    San Francisco Bay Area
  • Education
    University of Illinois at Urbana-Champaign
  • Work
    Retired Principal Software Engineer
  • Joined

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
I just wrote some notes based on my experience about C++. I hope this helps.
  • Education
    Chosun University, South Korea
  • Work
    Software Engineer
  • Joined
• Edited on• 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
C++ Jedi Master
  • Email
  • Location
    San Francisco Bay Area
  • Education
    University of Illinois at Urbana-Champaign
  • Work
    Retired Principal Software Engineer
  • Joined
classS{S(){}public:staticS*instance();};S*S::instance(){staticSinstance_obj;return&instance_obj;}
Enter fullscreen modeExit fullscreen mode

Again, the destructorwill 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(){staticS*constinstance_obj=newS{};returninstance_obj;}
Enter fullscreen modeExit fullscreen mode

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

Thread Thread
 
dinhluanbmt profile image
dinhluanbmt
I just wrote some notes based on my experience about C++. I hope this helps.
  • Education
    Chosun University, South Korea
  • Work
    Software Engineer
  • Joined

nice ! i got it

Thread Thread
 
pauljlucas profile image
Paul J. Lucas
C++ Jedi Master
  • Email
  • Location
    San Francisco Bay Area
  • Education
    University of Illinois at Urbana-Champaign
  • Work
    Retired Principal Software Engineer
  • Joined

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

I just wrote some notes based on my experience about C++. I hope this helps.
  • Education
    Chosun University, South Korea
  • Work
    Software Engineer
  • Joined

More fromdinhluanbmt

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp