Singleton class implementation using shared_ptr

前端 未结 3 1261
遇见更好的自我
遇见更好的自我 2021-02-09 17:58
#include 
#include 

using namespace std;

class Demo {
    static shared_ptr d;
    Demo(){}
public:    
    static shared_ptr         


        
相关标签:
3条回答
  • 2021-02-09 18:21

    My 2nd Question above is that how come private constructor called out side of class while instantiating the static member

    //    shared_ptr<Demo> Demo::d(new Demo); // private ctor is accepted 
    

    I think return local static wont work , see below example object destroyed twice

    #include <iostream>
    
    using namespace std;
    
    class Demo {
    public:
        static Demo & getInstance(){
            static Demo d;
            return d;
        }
        ~Demo(){
            cout << "Demo destroyed" << endl;
        }
    };
    
    void fun(){
        Demo l = Demo::getInstance();
    
    }
    int main()
    {
        fun();
       cout << "Hello World" << endl; 
    }
    
    0 讨论(0)
  • 2021-02-09 18:29

    This is not thread-safe: two threads calling getInstance would cause a data race. A common approach is to use a function-scope static variable:

    static shared_ptr<Demo> getInstance(){
      static shared_ptr<Demo> d(new Demo);
      return d;
    }
    

    Such a variable is guaranteed to be initialized exactly once, when control passes over its definition for the first time, and in a thread-safe manner.

    At this point though, it's not at all clear why you would want to use shared_ptr. You could just as well do

    static Demo& getInstance(){
      static Demo d;
      return d;
    }
    

    This is a textbook implementation of a singleton (well, one of).


    Re: initialize with a private constructor. I'm not sure I understand the nature of your confusion. Are you asking why Demo::getInstance can use private constructor of Demo? Well, because it's a member of Demo, and members of a class can access private members of that class. Are you asking why Demo::getInstance can call shared_ptr<Demo>::reset() passing a Demo* pointer? Well, because reset() is a public member function of shared_ptr, taking a pointer as a parameter. Which part of this process do you find controversial?

    0 讨论(0)
  • 2021-02-09 18:34

    Some comments from 1 to help with the discussion. Static variable will be destroyed uppon exit of the application, so we don't need to use the smart pointer at this stage as mentioned above.

    "If multiple threads attempt to initialize the same static local variable concurrently, the initialization occurs exactly once (similar behavior can be obtained for arbitrary functions with std::call_once).

    Note: usual implementations of this feature use variants of the double-checked locking pattern, which reduces runtime overhead for already-initialized local statics to a single non-atomic boolean comparison. (since C++11)

    The destructor for a block-scope static variable is called at program exit, but only if the initialization took place successfully. "

    0 讨论(0)
提交回复
热议问题