Boost logo

Boost Users :

From: Stephan Born (yg-boost-users_at_[hidden])
Date: 2002-10-08 11:14:20


Nicola Musatti wrote:
> Within the singleton class I hold the instance with a shared_ptr. I
> consider this the best option, as it guarantees the correct order of
> destruction when a singleton depends on another one.

But I *want* it to be delete automagically...and I do not see the
danger: if there is a dependent second_singleton it would hold a
shared_ptr to my singleton, and singleton would not be destroyed before
second_singleton is destroyed by its own. Maybe it should be made an
option by using policies....but I really do not the danger.

> You should rely on the constructor that takes an additional deleter
> argument, something like (not compiled and almost certainly incomplete
> and incorrect):
>
> class SingletonDeleter {
> friend class shared_ptr<Singleton>;
> operator() (Singleton *p) { delete p; }
> };
>
> class Singleton {
> friend class SingletonDeleter;
> public:
> shared_ptr<Singleton,SingletonDeleter> instance() {
> if ( inst == 0 )
> inst = shared_ptr<Singleton,SingletonDeleter> (
> new Singleton,SingletonDeleter());
> return inst;
> }
> };
>
> typedef shared_ptr<Singleton,SingletonDeleter> SingletonPtr;

Yes, I fear it *is* incorrect ;) look at the bottom of the posting for
my implelentation

>>Declaring the destructor as private is only possible when defining
>>boost::checked_delete as friend of the singleton-class.
>
> [...]
>
>>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.
>
>
> Moreover, you rely on what should be an implementation detail.

OK, I hope that this will be the correct way:
* I do not rely on implementation-detail ( make boost::checked_delete a
friend )
* I provide my own deleter-functor

<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, checked_deleter() ); // <-- NEW!!!
       s_instance = tmp;
     }
     else
     {
       tmp = boost::make_shared( s_instance );
     }

     return tmp;
   }

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

private:
   // NEW !!!!
   struct checked_deleter
   {
     operator() ( singleton * p_ )
     {
       // does the same as boost::checked_delete from BOOST 1.28.0
       typedef char type_must_be_complete[ sizeof( p_ ) ];
       delete p_;
     }
   };
   friend struct checked_deleter;

   typedef boost::weak_ptr< singleton > internal_singleton_ptr;

   singleton(){};
   ~singleton(){}; // NOW IT'S PRIVATE !!!

   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();

   // OK, these things do not work anymore.....
   //delete( another_ptr.get() );
   //boost::checked_delete( another_ptr.get() );
   //singleton::singleton_deleter deleter();
   //deleter( another_ptr.get() );

   another_ptr->foo();

   return 0;
}

</code>

-- 
---------------------------------------------------------------
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