0

Is there any difference or specific advice when it comes to the following approaches for defining singletons?

In 1, the singleton object is a class private static, but in 2, it's a file static.

Note: m_initedObj1 is just there to show that class has state, and use case is to call this singleton->DoSomething() many times, without needing to init this object again.

1)

// header file class Foo { private: static Foo* s_fooSingleton; Foo(); Obj1 m_initedObj1; public: static Foo* Singleton(); static void ClearSingleton(); Bar DoSomething(...); }; // cpp file Foo* Foo::s_fooSingleton = nullptr; Foo::Foo() { m_initedObj1 = InitObj1Somewhere(); } /*static*/ Foo* Foo::Singleton() { if(!Foo::s_fooSingleton) Foo::s_fooSingleton = new Foo(); return Foo::s_fooSingleton; } /*static*/ void Foo::ClearSingleton() { if(Foo::s_fooSingleton) delete Foo::s_fooSingleton; Foo::s_fooSingleton = nullptr; } Bar Foo::DoSomething(...) { // do something } 

2)

// header file class Foo { private: Foo(); Obj1 m_initedObj1; public: static Foo* Singleton(); static void ClearSingleton(); Bar DoSomething(...); }; // cpp file static Foo* s_fooSingleton = nullptr; Foo::Foo() { m_initedObj1 = InitObj1Somewhere(); } /*static*/ Foo* Foo::Singleton() { if(!s_fooSingleton) s_fooSingleton = new Foo(); return s_fooSingleton; } /*static*/ void Foo::ClearSingleton() { if(s_fooSingleton) delete s_fooSingleton; s_fooSingleton = nullptr; } Bar Foo::DoSomething(...) { // do something } 
8
  • 3
    in 2) other class methods can modify s_fooSingleton Commented Apr 6, 2017 at 5:31
  • 1
    Use Scott Meyer's singleton. Commented Apr 6, 2017 at 5:33
  • Or just don't use singletons ;-) Commented Apr 6, 2017 at 5:35
  • @JerryGoyal yeah, but let's say this file will only have this class, and even if they did, not a big problem. Commented Apr 6, 2017 at 5:42
  • @GuillaumeRacicot, yes i understand it's thread safe starting C++11. But for the above cases, is there any difference? Commented Apr 6, 2017 at 5:44

2 Answers 2

2

As JerryGoyal states in the comments, in 2) other methods in the same .cpp file can modify s_fooSingleton.

On the other hand, they are not both thread-safe. If you don't really mind the clearing (calling ClearSingleton() explicitly), just go with the Scott Meyers' version. Otherwise, go with the double checked locking version.

It's really hard to ensure the safety in case of explicitly deleting. You always have to check whether it's deleted before you access it. If it's a multi-threaded executable, checking and using it must be atomic, because it can be deleted just after checking.

Double checked locking could be used to create and delete the singleton, which ensures you that there is only one instance at a time. Yet, it does not ensure the object really exist, since you may accidentally delete it.

You may use smart pointers to count references and delete it if no references exist.

Or even better, see this answer https://stackoverflow.com/a/15733545/1632887.

I just wouldn't delete it explicitly if I were you!

Sign up to request clarification or add additional context in comments.

6 Comments

What do you mean "if you don't mind the clearing"? Wouldn't this singleton be destructed on its own?
i mean the ClearSingleton() function. It will be destructed in the end, but i thought that you want to call the ClearSingleton() function explicitly, which makes it even harder.
No that's fine. I can remove that function and its call. Thanks!
just curious... how would i destruct it on demand, if i need to?
i tried calling Foo::Singleton().~Foo(), which did call the destructor, but afterwards, if I call Singleton(), the same object is there (and works), without calling constructor again (added a few prints in the functions to track this).
|
0

Maybe this will satisfy you more:

class MyClass1 { private: MyClass1(){} public: MyClass1& Instance() { static MyClass1 theSingleInstance; return theSingleInstance; } }; class MyClass2 { private: MyClass2() {} public: MyClass2* Instance() { static MyClass2* theSingleInstance = new MyClass2; return theSingleInstance; } }; class MyClass3 { private: MyClass3() {} public: MyClass3* Instance() { static MyClass3 theSingleInstance; return &theSingleInstance; } }; 

1 Comment

The public Instance functions should be static, no?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.