I am currently learning how to use the C++11 smart pointers while programming a 2D game engine as a hobby using SDL. However, I ran into a problem while implementing an OOp wrapper for SDL.
The intent is to create a singleton class, which initializes SDL when it is constructed, and shuts SDL down when it gets destroyed. The singleton class has a static method getInstance
that returns a shared_ptr
to the singleton, and constructs the single instance if no instance exists, the idea being that all clients of the singleton own a shared_ptr
to it, and when all clients get destroyed, the singleton is also destroyed. I do understand that singletons (and other globals) are generally bad, but I think that this could be one of the few cases where a singleton is appropriate, as there can only be one SDL library in use.
The problem lies in returning the shared_ptr
from the getInstance
method. Instead of using the same shared_ptr
manager object, the shared_ptr
instances are unrelated, and destroying a single one of them deallocates the singleton.
#include <iostream>
#include <memory>
using namespace std;
class Foo
{
public:
~Foo(){cout << "Foo <" << this << "> destroyed\n"; instance_ = nullptr;}
static shared_ptr<Foo> getInstance()
{
if(instance_ == nullptr)
instance_ = new Foo;
//problem: the shared pointers created are unaware of each other
return shared_ptr<Foo>(instance_);
}
private:
Foo(){cout << "Foo <" << this << "> constructed\n";}
Foo(Foo& other){}
void operator=(Foo& other){}
static Foo* instance_;
};
Foo* Foo::instance_ = nullptr;
int main()
{
shared_ptr<Foo> a = Foo::getInstance();
shared_ptr<Foo> b = Foo::getInstance();
shared_ptr<Foo> c = Foo::getInstance();
}
Output:
Foo <0x3e2a10> constructed
Foo <0x3e2a10> destroyed
Foo <0x3e2a10> destroyed
Foo <0x3e2a10> destroyed