Boost logo

Boost Users :

From: Jason Winnebeck (yg-boost-users_at_[hidden])
Date: 2003-07-17 21:19:17


Can you multiply inherit from objects that inherit from
enable_shared_from_this? It seems not. My program compiled on MSVC.NET
"crashes" due to shared_from_this throwing boost::bad_weak_ptr.

Originally when I started using shared_ptr I wanted to have an ability
to obtain a shared_ptr to this since my objects sometimes register
themselves.

The way I do it now is like this:

static sptr create() {
   sptr ret( new Object() );
   ret->setThisPtr( ret );
   return ret;
}

However it is very easy to forget which classes you inherit from that
force you to call setThisPtr. A good use of the assert statement helps
but I'd rather not do this. The problem is that I use multiple
inheritance in one place:

static sptr create() {
   sptr ret( new ComplexObject() );
   ret->BaseA::setThisPtr( ret );
   ret->BaseB::setThisPtr( ret );
   return ret;
}

I thought I'd use enable_shared_from_this but as I said it crashes. The
following program as tested on MSVC.NET throws boost::bad_weak_ptr then
the line "Base2::sptr b2 = c->Base2::getThis();" is executed.

#include <iostream>
#include <boost/smart_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

using namespace std;

template <class T>
class SharedThis : public boost::enable_shared_from_this<T> {
public:
   boost::shared_ptr<T> getThis() {
     return shared_from_this();
   }
};

class Base1 : public SharedThis<Base1> {
public:
   typedef boost::shared_ptr<Base1> sptr;
   typedef boost::weak_ptr<Base1> wptr;

protected:
   Base1() { cout << "Base1 ctor" << endl; }

public:
   virtual ~Base1() { cout << "Base1 dtor" << endl; }

   static sptr create() {
     return sptr( new Base1() );
   }

private:
   Base1( const Base1& o );
   Base1& operator = ( const Base1& rhs );
};

//Base2 is identical to Base1 except different name
class Base2 : public SharedThis<Base2> {
public:
   typedef boost::shared_ptr<Base2> sptr;
   typedef boost::weak_ptr<Base2> wptr;

protected:
   Base2() { cout << "Base2 ctor" << endl; }

public:
   virtual ~Base2() { cout << "Base2 dtor" << endl; }

   static sptr create() {
     return sptr( new Base2() );
   }

private:
   Base2( const Base2& o );
   Base2& operator = ( const Base2& rhs );
};

class Child : public Base1, public Base2 {
public:
   typedef boost::shared_ptr<Child> sptr;
   typedef boost::weak_ptr<Child> wptr;

protected:
   Child() { cout << "Child ctor" << endl; }

public:
   virtual ~Child() { cout << "Child dtor" << endl; }

   static sptr create() {
     return sptr( new Child() );
   }
};

int main( int argc, char* argv[] ) {
   Child::sptr c = Child::create();
   Base1::sptr b1 = c->Base1::getThis();
   Base2::sptr b2 = c->Base2::getThis();

   /*
   assert( c.get() == c->Base1::getThis().get() );
   assert( c.get() == c->Base2::getThis().get() );
   assert( c == c->Base1::getThis() );
   assert( c == c->Base2::getThis() );
   */
}


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