enabled_shared_from_this: bad_weak_ptr exception + online doc explanation

Hi all, I have a class called TextTool. In its constructor I initialize a member variable. This member variable needs a pointer to TextTool in *its*constructor. Hence I need to have a pointer to "this" (TextTool) and then pass it to the constructor of the member variable. This is a summery of my code: *TextTool.h* class TextTool : public Tool, public boost::enable_shared_from_this<TextTool> { public: TextTool(QDialog *taskDialogue); private: boost::shared_ptr<ToggleControl> bold; //Member variable that needs a pointer to TextTool in its constructor }; *TextTool.cpp* TextTool::TextTool(QDialog *taskDialogue) : Tool(this->name) { boost::shared_ptr<TextTool> pointerToThis = TextTool::shared_from_this(); //ERROR OCCURS ON THIS LINE bold = boost::shared_ptr<ToggleControl>(new ToggleControl(pointerToThis)); } I get a runtime exception: "boost::bad_weak_ptr at memory location 0x0012fccc" when executing the above mentioned line. On the BOOST online documentation, I dont understand what this line means: "**this* must be a subobject of an instance *t* of type *T* . There must exist at least one *shared_ptr* instance *p* that *owns* *t*.". Do I need to have an instance (t) of TextTool (T) as a member variable of the class TextTool? Won't this lead to loops in my situation (since I want the "this" pointer to be created in the constructor itself)? Any help? Thanks, /C.

TextTool::TextTool(QDialog *taskDialogue) : Tool(this->name) { boost::shared_ptr<TextTool> pointerToThis = TextTool::shared_from_this(); //ERROR OCCURS ON THIS LINE
bold = boost::shared_ptr<ToggleControl>(new ToggleControl(pointerToThis)); }
You cannot call shared_from_this in the constructor. Instead, you can define a static constructing method, like this: // untested!! static boost::shared_ptr<TextTool> TextTool::create(QDialog *taskDialogue) { boost::shared_ptr<TextTool> pointerToThis(new TextTool(taskDialogue)); pointerToThis->bold.reset(new ToggleControl(pointerToThis)); return pointerToThis; }

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Saturday 06 September 2008 15:10 pm, Igor R wrote:
TextTool::TextTool(QDialog *taskDialogue) : Tool(this->name) { boost::shared_ptr<TextTool> pointerToThis = TextTool::shared_from_this(); //ERROR OCCURS ON THIS LINE
bold = boost::shared_ptr<ToggleControl>(new ToggleControl(pointerToThis)); }
You cannot call shared_from_this in the constructor. Instead, you can define a static constructing method, like this:
Actually, you can use shared_from_this with the boost from svn trunk. I don't know when/if this feature will make it into a release though. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFIxSLy5vihyNWuA4URAtZ2AJ4vrARqO6k15uk8wskm5ml4MDURsQCgiIaY 0KZx8D/jKW75e71dkazGLnY= =rqYm -----END PGP SIGNATURE-----

Thanks for the reply. But I am still unsure where I should invoke this
static method.
1) I need the member variables initialized...and if I cant do it in the
constructor, then where should I?
2) Also, your sample code does not use shared_from_this() ... I would like
to learn how to correctly use shared_from_this() because I'll be using it in
other places in my code too.
Thanks,
/C.
2008/9/6 Igor R
TextTool::TextTool(QDialog *taskDialogue) : Tool(this->name) { boost::shared_ptr<TextTool> pointerToThis = TextTool::shared_from_this(); //ERROR OCCURS ON THIS LINE
bold = boost::shared_ptr<ToggleControl>(new ToggleControl(pointerToThis)); }
You cannot call shared_from_this in the constructor. Instead, you can define a static constructing method, like this:
// untested!! static boost::shared_ptr<TextTool> TextTool::create(QDialog *taskDialogue) { boost::shared_ptr<TextTool> pointerToThis(new TextTool(taskDialogue)); pointerToThis->bold.reset(new ToggleControl(pointerToThis)); return pointerToThis; } _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

1) I need the member variables initialized...and if I cant do it in the constructor, then where should I?
Since in the current version you cannot call shared_from_this() in a constructor, you can't initialize your members with an expression that invloves shared_from_this(). Instead, you can set your shared_ptr's in some initializing member function that would be called after the object is constructed: struct B; struct A { A(shared_ptr<B> b) { //... } }; class B : public enable_shared_from_this<B> { shared_ptr<A> a_; public: void init() { a_.reset(new A(shared_from_this())); } }; main() { shared_ptr<B> b(new B); b->init(); } ...also you can wrap initialization in a static constructing function: class B.... { // like in the previous example B() {} public: static shared_ptr<B> create() { shared_ptr<B> result(new B()); result->init(); return result; } }; main() { shared_ptr<B> b(B::create()); }
2) Also, your sample code does not use shared_from_this() ... I would like to learn how to correctly use shared_from_this() because I'll be using it in other places in my code too.
Please, refer to the "Smart Pointer Programming Techniques" section: http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/sp_techniques.html#from_...
participants (3)
-
cxv@sfu.ca
-
Frank Mori Hess
-
Igor R