0

which one of singleton implementation is better and what are advantages and disadvantages?

//first

class singleton_SharedPtr{
public:
singleton_SharedPtr(const singleton_SharedPtr&) = delete;
singleton_SharedPtr& operator=(const singleton_SharedPtr&) = delete;
~singleton_SharedPtr(){}

//is it normal to return weak_ptr instead of share_ptr in the getInstance method????
static std::shared_ptr<int> getInstance(){
    std::cout<<"referenced before if condfition, use_count : "<<instance.use_count()<<std::endl;
    if(instance==nullptr){
        instance=std::make_shared<int>();
    }
    std::cout<<"referenced after if condfition, use_count : "<<instance.use_count()<<std::endl;
    return instance;
}
private:
singleton_SharedPtr(){}
static std::shared_ptr<int> instance;
};
std::shared_ptr<int> singleton_SharedPtr::instance=nullptr;

//second

class singleton_UniquePtr{
public:
singleton_UniquePtr(const singleton_UniquePtr&) = delete;
singleton_UniquePtr& operator=(const singleton_UniquePtr&) = delete;
~singleton_UniquePtr(){}
static int* getInstance(){
    if(instance==nullptr){
        instance=std::make_unique<int>();
    }else
        std::cout<<"instance.get: "<<instance.get()<<std::endl;
    return instance.get();
}
private:
singleton_UniquePtr(){}
static std::unique_ptr<int> instance;
};
std::unique_ptr<int> singleton_UniquePtr::instance=nullptr;

we need to access to instance inside the loop. will memory leakage happen or not? if yes, which one of them cause to memory leakag.

//1:
while(1){std::shared_ptr<int>sharedPtr=
singleton_SharedPtr::getInstance();
    //use sharePtr...
    //...
}

//2:
 while(1){
 std::weak_ptr<int>weakPtr=singleton_SharedPtr::getInstance();
    //use sharePtr...
    //...
}


//3:
while(1){
    int* rawPtr=singleton_UniquePtr::getInstance();
    //use rawPtr...
     //...
    if(rawPtr){
        delete rawPtr;
        rawPtr=nullptr;
    }
}

any suggestion about detail of performance ,memory leakage ,being standard and ... ? thank you very much.

  • Questions of the form what "is better and what are advantages and disadvantages" are asking for opinions. All of the shown approaches work differently, and will be better or worse in different ways. The decision of how they should be used is entirely up to you, and you will need to make that decision yourself based on the specific requirements of whatever program you need to write. It may very well be that for some programs it will be "better" to do this one way, and for other programs one of the other alternatives will be "better". – Sam Varshavchik Nov 26 '20 at 23:07
  • 1
    I think you are overthinking this. What is the point of a shared pointer to a singleton? The [owner](https://stackoverflow.com/questions/49024982/what-is-ownership-of-resources-or-pointers) of the singleton is clear: The singleton owns the singleton. Instead, may I suggest you take a look at [the Meyers Singleton](https://stackoverflow.com/a/1008289/4581301)? No pointers involved what-so-ever. Threadsafe as of C++11. – user4581301 Nov 26 '20 at 23:20

1 Answers1

0

Don't create a singleton with a smart pointer.I would say use

class Singleton {
public:
    static public Singleton* instance() {
        static Singleton* s_instance = new Singleton();
        return s_instance();
    }
private:
    Singleton() {}
};

The pointer will never be deleted but since it is create once and last the entire length of your program this should be not an issue. Anything that cleans up on shutdown will likely result in dependency hell which is a whole lot worse. Smart pointer make no sense with the singleton instance since ownership is global static space. Smart pointer are to enforce clear pointer ownership which is not an issue in this case.

doron
  • 27,972
  • 12
  • 65
  • 103
  • There is one case where shared pointer makes a smidgeon of sense, but it means you have a bigger design problem lurking: Another static object that is being destroyed after the singleton is still using the singleton. If you think `shared_ptr` is the solution to this problem, you have two problems. – user4581301 Nov 26 '20 at 23:56
  • Side note: Don't forget to `delete` the copy constructor and assignment operator. – user4581301 Nov 26 '20 at 23:58
  • So why pointer at all? A simple static object in `instance` and a reference `return`. Omitted dtor is a a sign of bad design. Also, if the intent is to access an object of in-built type such as `int`, why bother with a class? Just a function returning a reference to the nested `static` variable would suffice; neat & clean. – Red.Wave Nov 27 '20 at 09:16
  • I like the pointer because it ensures the destuctors is never called. Will save a tonne of dependency hell. – doron Nov 27 '20 at 12:23