Boost logo

Boost Users :

From: Stephan Born (yg-boost-users_at_[hidden])
Date: 2002-10-07 10:39:36


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?

<code>

#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/utility.hpp>

class singleton : boost::noncopyable
{
public:
   typedef boost::shared_ptr< singleton > singleton_ptr;

   static singleton_ptr instance()
   {
     singleton_ptr tmp;

     if( s_instance.expired() )
     {
       tmp.reset( new singleton );
       s_instance = tmp;
     }
     else
     {
       tmp = boost::make_shared( s_instance );
     }

     return tmp;
   }

   void foo()
   {
     // do something
     i++;
   }

   // like to make it private in order to prohibit delete on it,
   // but boost::shared_ptr<> can't handle it....so sad :(
   ~singleton(){};

private:
   typedef boost::weak_ptr< singleton > internal_singleton_ptr;

   singleton(){};
   int i;

   static internal_singleton_ptr s_instance;
};

singleton::internal_singleton_ptr singleton::s_instance;

int main()
{
   {
     singleton::singleton_ptr first_ptr = singleton::instance();

     {
       singleton::singleton_ptr second_ptr = singleton::instance();
       second_ptr->foo();
     }

     first_ptr->foo();
   }

   singleton::singleton_ptr another_ptr = singleton::instance();

   another_ptr->foo();

   return 0;
}

</code>

Regards, Stephan

-- 
---------------------------------------------------------------
Dipl.-Inf. (FH) Stephan Born   | beusen Solutions GmbH
fon: +49 30 549932-0           | Landsberger Allee 366
fax: +49 30 549932-21          | 12681 Berlin
mailto:stephan.born_at_[hidden]  | Germany
---------------------------------------------------------------
        PGP-Key verfügbar       |      PGP-Key available
---------------------------------------------------------------

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net