
(new Derived()); }
Fellow boosters, A little while ago I found a pernicious problem with enable_shared_from_this when used with multiple inheritance. Here is an example: #include <boost/smart_ptr.hpp> #include <boost/enable_shared_from_this.hpp> class Base1 : public boost::enable_shared_from_this< Base1 > { public: Base1() {} virtual ~Base1() {} boost::shared_ptr< Base1 > GetBase1() { return shared_from_this(); } }; class Base2 : public boost::enable_shared_from_this< Base2 > { public: Base2() {} virtual ~Base2() {} boost::shared_ptr< Base2 > GetBase2() { return shared_from_this(); } }; class Derived : public Base1, public Base2 { }; int main() { boost::shared_ptr< Derived > wDerived(new Derived()); // Either of the following lines crashes with GCC, but the first one // passes on VS2005 boost::shared_ptr< Base1 > wBase1 = wDerived->GetBase1(); boost::shared_ptr< Base2 > wBase2 = wDerived->GetBase2(); return 0; } Since Derived inherits from two bases that each inherits from enable_shared_from_this, it has two internal weak_ptr. These weak_ptr are usualy initialised in the constructor of the shared_ptr and I have observed two different behavior with the above code depending if I build it with VS2005 or GCC. With VS2005, the first base class in the inheritance list of Derived (here Base1) get its internal weak_ptr initialized, but not the second one, thus it crashes when we try to access the Base2 weak_ptr via shared_from_this. On GCC, neither base classes get their internal weak_ptr initialized and both base classes access to their internal weak_ptr provokes a crash. To prevent that kind of problem, I created a SmartPtrBuilder and a (very) slightly modified EnabledSharedFromThis (only one assert was removed). Here is the same program with the modifications: #include <boost/smart_ptr.hpp> #include "EnableSharedFromThis.h" #include "SmartPtrBuilder.h" class Base1 : public Generic::EnableSharedFromThis< Base1 > { public: Base1() {} virtual ~Base1() {} boost::shared_ptr< Base1 > GetBase1() { return SharedFromThis(); } }; class Base2 : public Generic::EnableSharedFromThis< Base2 > { public: Base2() {} virtual ~Base2() {} boost::shared_ptr< Base2 > GetBase2() { return SharedFromThis(); } }; class Derived : public Base1, public Base2 { public: // Factory method static boost::shared_ptr< Derived > Create() { return Generic::SmartPtrBuilder::CreateSharedPtr< Base1, Base2 private: Derived() {} }; int main() { boost::shared_ptr< Derived > wDerived = Derived::Create(); // No more crashes boost::shared_ptr< Base1 > wBase1 = wDerived->GetBase1(); boost::shared_ptr< Base2 > wBase2 = wDerived->GetBase2(); return 0; } As you can see, Derived has now a factory method that uses the SmartPtrBuilder to create the shared_ptr. Two template arguments are used on CreateSharedPtr, allowing it to initialize the internal weak_ptr of each base classes. The SmartPtrBuilder I did can support up to 10 base classes as template arguments and I also did a variadic template version which has no limit. By using the factory method, the users of Derived don't need to know which of its base classes need its internal weak_ptr need to be initialized. Source code for the SmartPtrBuilder and the modified EnableSharedFromThis: http://spoluck.ca:8000/boost/EnableSharedFromThis.h http://spoluck.ca:8000/boost/SmartPtrBuilder.h That builder might be incorporated to the boost smart pointer library so that anyone could use its facilities to prevent the problem mentioned earlier. No modification to the mighty shared_ptr class required, only the addition of a builder. What do you think? Philippe