Newby question re (boost::shared_ptr) enable_shared_from_this
Hi, I'm still fairly new to C++ and I'm in the process of converting pointers to boost shared pointers. I have a question regarding the use of enable_shared_from_this. I would like to store a self-referencing pointer within the object. Something like: class someclass : public boost::enable_shared_from_this<someclass> { protected: boost::shared_ptr<someclass> m_ptr_this; someclass() { m_ptr_this = shared_from_this(); } } And then access m_ptr_this in classes derived from someclass, and pass as a parameter to methods of other (derived or non-derived) classes. eg. class someclass2 : public someclass { ... some_func(){ someclass3* f = new someclass3(); someclass3->do_something( m_ptr_this ); } } I understand that using a shared_ptr (without enable_shared_from_this) to self-reference will lead to problems because the reference count of the pointer will never reach zero and therefore the memory will never get released. But as enable_shared_from_this uses a weak pointer internally, does this get around the problem? I'm getting a little confused because it gets typecast from weak_ptr to shared_ptr and I'm not sure what this leads to. I've also considered having a member function return the pointer: boost::shared_ptr<someclass> someclass::get_this() { return shared_from_this(); } and then calling the routine like this; someclass3->do_something( get_this() ); but I think that this will cause a problem because the documentation says not to use boost pointers which are only created as temporary variables. i.e. store all boost pointers in vars. What I'm hoping to do is avoid having to declare extra shared_ptr vars all over the place. Any help will be most appreciated. And I'll owe you a beer! Regards Ethann Castell
Hi, I would like to store a self-referencing pointer within the object.
Something like:
class someclass : public boost::enable_shared_from_this<someclass> { protected: boost::shared_ptr<someclass> m_ptr_this; someclass() { m_ptr_this = shared_from_this(); } }
A self-referencing smart pointer within your object is not necessary if you are using enable_shared_from_this. By calling shared_from_this() you can obtain a shared_ptr to this when you need it. Otherwise you are creating a vicious circle and your reference count will never reach zero again. Please note that enable_shared_from_this requires the existence of at least one shared_ptr instance that owns your object. That is, before you are allowed to call shared_from_this() your object has to be under control of a smart pointer. That's why you cannot use shared_from_this in the object's constructor. It's very important to understand this point correctly. I recommend to create a factory function for your class: class someclass { ... public: shared_ptr<someclass> CreateSomeClass() { shared_ptr<someclass> p(new someclass); return p; } } I understand that using a shared_ptr (without enable_shared_from_this) to
self-reference will lead to problems because the reference count of the pointer will never reach zero and therefore the memory will never get released.
Yes, that's correct and is true for enable_shared_from_this, too. But as enable_shared_from_this uses a weak pointer internally, does this
get around the problem? I'm getting a little confused because it gets typecast from weak_ptr to shared_ptr and I'm not sure what this leads to.
As enable_shared_from_this relies on at least one external reference to *this a weak pointer is sufficient.
boost::shared_ptr<someclass> someclass::get_this() { return shared_from_this(); }
but I think that this will cause a problem because the documentation says not to use boost pointers which are only created as temporary variables. i.e. store all boost pointers in vars.
In this case the shared_ptr is not temporary because there's already a shared_ptr (an external one) which owns the object. Best regards, Philipp
A big thanks to Phillip and Brian for their help so far. You've helped me
increase my understanding of how shared_ptr's and enable_shared_from_this
work.
I've taken on board what you've both said but I still feel like I am
missing something. I'm getting bad_weak_ptr exceptions (resulting in
memory leaks) which make no sense to me. I've debugged through the code
and checked the use_count and weak_count. The use_count looks ok but I'm
not sure about the weak_count.
I have a base class which contains the shared_from_this and a hierarchy of
extended classes that inherit from the base class. The extended classes
pass pointer's to themselves, to the other classes, so that linkages can
be formed between them( at the base class level ).
class base_class:: public shared_from_this
prviate:
boost::shared_ptr
The class you want to inherit from is "enabled_shared_from_this" not "shared_from_this" ethann.castell@caliton.com wrote:
A big thanks to Phillip and Brian for their help so far. You've helped me increase my understanding of how shared_ptr's and enable_shared_from_this work.
I've taken on board what you've both said but I still feel like I am missing something. I'm getting bad_weak_ptr exceptions (resulting in memory leaks) which make no sense to me. I've debugged through the code and checked the use_count and weak_count. The use_count looks ok but I'm not sure about the weak_count.
I have a base class which contains the shared_from_this and a hierarchy of extended classes that inherit from the base class. The extended classes pass pointer's to themselves, to the other classes, so that linkages can be formed between them( at the base class level ).
class base_class:: public shared_from_this prviate: boost::shared_ptr
m_Linked; // link to another base_class base_class::base_class( boost::shared_ptr
pLinked) { m_Linked = pLinked; // store link to other base class } class B : public base_class B::B(boost::shared_ptr
pLinked) : base_class( pLinked) class B1 : public B B1::B1(boost::shared_ptr
pLinked) : B( pLinked) class B2 : public B1 B2::B2(boost::shared_ptr
pLinked) : B1( pLinked) class A : public base_class
classA::Process() { boost::shared_ptr<A> ptr_a = shared_from_this(); // get pointer to myself
//afterwards - use_count = 2, weak_count = 2 ... if (some_condition){ boost::shared_ptr<B2> ptr_b2( ptr_a) ; // create new B2 and pass pointer to me. }else{ // crashes with bad_weak_ptr error on this line. } }
main() { boost::shared_ptr<A> ptr_a( new A() ); ptr_a->process }
It looks a little like ptr_a is being destroyed at the }else{ statement (although I would have expected this at the end of Process(). At the else statement ptr_a.use_count = 3, which I believe to be correct.
I've tried passing the boost pointers by value, by reference and also as constants but none of these make a difference.
Any ideas?
------------------------------------------------------------------------
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Typo on my part in this email. I've used enable_shared_from_this in my real code. Any other ideas? The class you want to inherit from is "enabled_shared_from_this" not "shared_from_this" ethann.castell@caliton.com wrote:
A big thanks to Phillip and Brian for their help so far. You've helped me increase my understanding of how shared_ptr's and enable_shared_from_this work.
I've taken on board what you've both said but I still feel like I am missing something. I'm getting bad_weak_ptr exceptions (resulting in memory leaks) which make no sense to me. I've debugged through the code and checked the use_count and weak_count. The use_count looks ok but I'm not sure about the weak_count.
I have a base class which contains the shared_from_this and a hierarchy of extended classes that inherit from the base class. The extended classes pass pointer's to themselves, to the other classes, so that linkages can be formed between them( at the base class level ).
class base_class:: public shared_from_this prviate: boost::shared_ptr
m_Linked; // link to another base_class base_class::base_class( boost::shared_ptr
pLinked) { m_Linked = pLinked; // store link to other base class } class B : public base_class B::B(boost::shared_ptr
pLinked) : base_class( pLinked) class B1 : public B B1::B1(boost::shared_ptr
pLinked) : B( pLinked) class B2 : public B1 B2::B2(boost::shared_ptr
pLinked) : B1( pLinked) class A : public base_class
classA::Process() { boost::shared_ptr<A> ptr_a = shared_from_this(); // get pointer to myself
//afterwards - use_count = 2, weak_count = 2 ... if (some_condition){ boost::shared_ptr<B2> ptr_b2( ptr_a) ; // create new B2 and pass pointer to me. }else{ // crashes with bad_weak_ptr error on this line. } }
main() { boost::shared_ptr<A> ptr_a( new A() ); ptr_a->process }
It looks a little like ptr_a is being destroyed at the }else{ statement (although I would have expected this at the end of Process(). At the else statement ptr_a.use_count = 3, which I believe to be
correct.
I've tried passing the boost pointers by value, by reference and also as constants but none of these make a difference.
Any ideas?
------------------------------------------------------------------------
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On 1/22/07, ethann.castell@caliton.com
class A : public base_class
classA::Process() { boost::shared_ptr<A> ptr_a = shared_from_this(); // get pointer to myself
//afterwards - use_count = 2, weak_count = 2 ... if (some_condition){ boost::shared_ptr<B2> ptr_b2( ptr_a) ; // create new B2 and pass pointer to me. }else{ // crashes with bad_weak_ptr error on this line. } }
boost::shared_ptr<B2> ptr_b2( ptr_a) does not create a new object of B2. Do you mean ptr_b2(new B2(ptr_a))? Could you please post a more complete code sample (at least of Process)?
participants (3)
-
Brian Crowder
-
ethann.castell@caliton.com
-
Philipp Henkel