|
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