From: "Stephan Born"
Hello!
I do some experiments on shared_ptr and weak_ptr. So I tried to use them for a singleton-class, which does not need an explicit singleton::release_instance method. The singleton-instance will be destroyed everytime the last external shared_ptr holding the instance goes out of scope. Is this a valid usage for weak_ptr? Are there any traps I do not see using these smart_ptrs in this context?
The drawback of using shared_ptr with singleton is the need for a public destructor. But this is dangerous....it is possible to write
singleton::singleton_ptr first_ptr = singleton::instance(); delete first_ptr.get();
Declaring the destructor as private is only possible when defining boost::checked_delete as friend of the singleton-class. ( there is a thread on comp.lang.c++.moderated with the topic 'specialization of function template as friend with MSVC6SP5 not possible' which deals with this problem of friendship... ) But then it is still possible to write the following code
singleton::singleton_ptr first_ptr = singleton::instance(); boost:checked_delete( first_ptr.get() );
OK, it's very unlikely to do it by chance, but it is possible.
Is there a way to allow destruction of the instance only to shared_ptr?
Your class isn't a "canonical" singleton since those have one instance per program; yours has one instance at a time. That aside, there are two ways to prohibit deletion: 1. Make the destructor protected and return an instance of a derived class: X.hpp: class X { protected: ~X(); public: shared_ptr<X> instance(); }; X.cpp: class X_impl: public X // not visible to clients { }; shared_ptr<X> X::instance() { return shared_ptr<X>(new X_impl); } 2. Use a custom private deallocator: class X { private: ~X(); static void destroy(X * p) { delete p; } public: shared_ptr<X> instance() { return shared_ptr<X>(new X, X::destroy); } };