Problem with enable_shared_from_this and shared_ptr
If class "Pool" inherits from enable_shared_from_this the documentation
says I'm able to do the following.
shared_ptr<Pool> aPool = shared_from_this();
The minimal code I've included shows that this isn't happening. The
code compiles but I get this error "tr1::bad_weak_ptr". What should I
be doing different?
Ryan
[CODE]
//C++ Includes
#include <exception>
#include <iostream>
#include <vector>
#include <algorithm>
//Boost Includes
#include
Ryan McConnehey wrote:
If class "Pool" inherits from enable_shared_from_this the documentation says I'm able to do the following.
shared_ptr<Pool> aPool = shared_from_this();
The minimal code I've included shows that this isn't happening. The code compiles but I get this error "tr1::bad_weak_ptr". What should I be doing different?
Ryan
[CODE]
//C++ Includes #include <exception> #include <iostream> #include <vector> #include <algorithm>
//Boost Includes #include
#include class pool : public boost::enable_shared_from_this< pool > { private: using boost::enable_shared_from_this< pool >::shared_from_this;
public: boost::shared_ptr<int> get(void) { boost::shared_ptr<pool> aPool = shared_from_this(); //This is where the tr1::bad_weak_ptr happens.
Ryan - See the documentation here: http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/enable_shared_from_this.... There must be at least one shared_ptr instance that owns the object that you are calling shared_from_this() on. Also see the examples at the above link. hth - michael -- ---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com
Michael Caisse wrote:
Ryan McConnehey wrote:
If class "Pool" inherits from enable_shared_from_this the documentation says I'm able to do the following.
shared_ptr<Pool> aPool = shared_from_this();
The minimal code I've included shows that this isn't happening. The code compiles but I get this error "tr1::bad_weak_ptr". What should I be doing different?
Ryan
[CODE]
//C++ Includes #include <exception> #include <iostream> #include <vector> #include <algorithm>
//Boost Includes #include
#include class pool : public boost::enable_shared_from_this< pool > { private: using boost::enable_shared_from_this< pool >::shared_from_this;
public: boost::shared_ptr<int> get(void) { boost::shared_ptr<pool> aPool = shared_from_this(); //This is where the tr1::bad_weak_ptr happens.
Ryan -
See the documentation here: http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/enable_shared_from_this....
There must be at least one shared_ptr instance that owns the object that you are calling shared_from_this() on. Also see the examples at the above link.
hth - michael
I've looked at that documentation already. That's part of why of I know I should be able to do what I want. Ryan
Ryan McConnehey wrote:
Michael Caisse wrote:
Ryan -
See the documentation here: http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/enable_shared_from_this....
There must be at least one shared_ptr instance that owns the object that you are calling shared_from_this() on. Also see the examples at the above link.
hth - michael
I've looked at that documentation already. That's part of why of I know I should be able to do what I want.
Ryan
Not very carefully... so let me quote from the above link directly: --------------- template<class T> shared_ptr<T const> enable_shared_from_this<T>::shared_from_this() const; *Requires:* *enable_shared_from_this<T>* must be an accessible base class of *T*. **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* ------------------- -- ---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com
Michael Caisse wrote:
Ryan McConnehey wrote:
Michael Caisse wrote:
Ryan -
See the documentation here: http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/enable_shared_from_this....
There must be at least one shared_ptr instance that owns the object that you are calling shared_from_this() on. Also see the examples at the above link.
hth - michael
I've looked at that documentation already. That's part of why of I know I should be able to do what I want.
Ryan
Not very carefully... so let me quote from the above link directly:
---------------
template<class T> shared_ptr<T const> enable_shared_from_this<T>::shared_from_this() const;
*Requires:* *enable_shared_from_this<T>* must be an accessible base class of *T*. **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*
-------------------
Your right. I didn't understand that part very well. After I put pool in a shared_ptr it worked fine. Thanks for your help. Ryan
Ryan,
Is there any chance you can post what you added to your provided example to
fix the problem you were having? I would love to see what that example looks
like when it is working.
Thanks in advance
Ganesh
On Tue, Jul 20, 2010 at 10:59 PM, Ryan McConnehey
Michael Caisse wrote:
Ryan McConnehey wrote:
Michael Caisse wrote:
Ryan -
See the documentation here: < http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/enable_shared_from_this.html>
There must be at least one shared_ptr instance that owns the object that you are calling shared_from_this() on. Also see the examples at the above link.
hth - michael
I've looked at that documentation already. That's part of why of I know I should be able to do what I want.
Ryan
Not very carefully... so let me quote from the above link directly:
---------------
template<class T> shared_ptr<T const> enable_shared_from_this<T>::shared_from_this() const;
*Requires:* *enable_shared_from_this<T>* must be an accessible base class of *T*. **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*
-------------------
Your right. I didn't understand that part very well. After I put pool in a shared_ptr it worked fine. Thanks for your help.
Ryan
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Ganeshram Iyer Open Source and CAD: http://ossandcad.blogspot.com ganeshramiyer@yahoo.com
Ganesh,
I think he did this:
int main(int argc, char * argv[]) {
try {
boost::shared_ptr<pool> myPool(new pool); //changed line
boost::shared_ptr<int> a = myPool->get();
}
catch (std::exception & exception) {
std::cout << exception.what() << std::endl;
}
return 0;
}
Regards,
Ovanes
On Wed, Jul 21, 2010 at 4:47 PM, Ganeshram Iyer
Ryan, Is there any chance you can post what you added to your provided example to fix the problem you were having? I would love to see what that example looks like when it is working. Thanks in advance Ganesh
[...]
Aaah, OK. Thank you so much Ovanes. For some odd reason I thought the change
would be in 'class pool'. Your sample code really helped alleviate my
misconception.
Thank you
Ganesh
On Wed, Jul 21, 2010 at 12:42 PM, Ovanes Markarian
Ganesh,
I think he did this:
int main(int argc, char * argv[]) { try { boost::shared_ptr<pool> myPool(new pool); //changed line
boost::shared_ptr<int> a = myPool->get(); } catch (std::exception & exception) { std::cout << exception.what() << std::endl; }
return 0;
}
Regards, Ovanes
On Wed, Jul 21, 2010 at 4:47 PM, Ganeshram Iyer
wrote: Ryan, Is there any chance you can post what you added to your provided example to fix the problem you were having? I would love to see what that example looks like when it is working. Thanks in advance Ganesh
[...]
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Ganeshram Iyer Open Source and CAD: http://ossandcad.blogspot.com ganeshramiyer@yahoo.com
Thanx Ryan. Very helpful. You have a comment that "This is where the
tr1::bad_weak_ptr happens". Is this something that still needs to be
addressed in your code or is there a solution already?
Thanks in advance
Ganesh
On Fri, Aug 6, 2010 at 2:40 AM, Ryan McConnehey
Ganeshram Iyer wrote:
Ryan, Is there any chance you can post what you added to your provided example to fix the problem you were having? I would love to see what that example looks like when it is working. Thanks in advance Ganesh
Sorry for the delay in answering your question. I missed it in my inbox. Anyway I've included what I changed in the code. I didn't see any point in giving the user a choice in how pool was created when one of the option gives an error. So, I added a static methods that creates a pool in a shared_ptr and hid the constructor. This forced the user to get the pool inside a shared_ptr and removed the possibility of an error when calling the get method.
Ryan
[CODE]
//C++ Includes #include <exception> #include <iostream> #include <vector> #include <algorithm>
//Boost Includes #include
#include class pool : public boost::enable_shared_from_this< pool > { private: using boost::enable_shared_from_this< pool >::shared_from_this;
private: pool(){}
public: static boost::shared_ptr<pool> create(void) { return boost::shared_ptr<pool>(new pool); }
public: boost::shared_ptr<int> get(void) { boost::shared_ptr<pool> aPool = shared_from_this(); //This is where the tr1::bad_weak_ptr happens. return boost::shared_ptr<int>(new int); } };
int main(int argc, char * argv[]) { try { boost::shared_ptr<pool> myPool = pool::create();
boost::shared_ptr<int> a = myPool->get(); } catch (std::exception & exception) { std::cout << exception.what() << std::endl; }
return 0; }
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Ganeshram Iyer Open Source and CAD: http://ossandcad.blogspot.com ganeshramiyer@yahoo.com
There must be at least one shared_ptr instance that owns the object that you are calling shared_from_this() on. Also see the examples at the above link.
My smart pointers, which are very similar to shared_ptr and weak_ptr, differ strongly in this respect in terms of initial concept: The "lost and found" principle allows you to obtain a smart pointer from this or other dumb pointer, and it always works, regardless of whether other smart pointers currently exist. To me, that follows from the original idea of smart pointers and multithreaded programming: you don't know who is going to be the last one out! As an early example (I published articles on the ideas in the mid '90s), it didn't stand up to standardization because it is difficult to achieve efficiently if it is non-intrusive. However, I don't see why a class that _does_ derive from the special supporting base class can't have full "lost and found" semantics, such that no special obtaining call is needed -- any smart pointer created from the object plays properly with any others that already exist. Meanwhile, those that don't derive from the special base class (non-intrusive) don't support lost-and-found and must only construct a smart pointer once. I'm sure the template metaprogramming is _much_ better now, both in technique and in what the compiler can actually swallow. So certainly the code that creates a smart pointer from a raw pointer can do one thing if T is derived from the special base class (find the existing smarts) and something else otherwise (create fresh smarts and prey that it's not been done before). I could almost do it in 1994 with badly broken templates that barely functioned for pedestrian parameterized types (had to add a line for non-intrusive types to support), but today it's no sweat to match "all types having can_handle as a base class" using enable_if, and void* for those that aren't. So, my point is that the shared_ptr can be improved in this area, without major changes. --John TradeStation Group, Inc. is a publicly-traded holding company (NASDAQ GS: TRAD) of three operating subsidiaries, TradeStation Securities, Inc. (Member NYSE, FINRA, SIPC and NFA), TradeStation Technologies, Inc., a trading software and subscription company, and TradeStation Europe Limited, a United Kingdom, FSA-authorized introducing brokerage firm. None of these companies provides trading or investment advice, recommendations or endorsements of any kind. The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.
On Thu, Jul 22, 2010 at 03:48:03PM -0400, John Dlugosz wrote:
There must be at least one shared_ptr instance that owns the object that you are calling shared_from_this() on. Also see the examples at the above link.
My smart pointers, which are very similar to shared_ptr and weak_ptr, differ strongly in this respect in terms of initial concept: The "lost and found" principle allows you to obtain a smart pointer from this or other dumb pointer, and it always works, regardless of whether other smart pointers currently exist. To me, that follows from the original idea of smart pointers and multithreaded programming: you don't know who is going to be the last one out!
As an early example (I published articles on the ideas in the mid '90s), it didn't stand up to standardization because it is difficult to achieve efficiently if it is non-intrusive. However, I don't see why a class that _does_ derive from the special supporting base class can't have full "lost and found" semantics, such that no special obtaining call is needed -- any smart pointer created from the object plays properly with any others that already exist. Meanwhile, those that don't derive from the special base class (non-intrusive) don't support lost-and-found and must only construct a smart pointer once.
I'm sure the template metaprogramming is _much_ better now, both in technique and in what the compiler can actually swallow. So certainly the code that creates a smart pointer from a raw pointer can do one thing if T is derived from the special base class (find the existing smarts) and something else otherwise (create fresh smarts and prey that it's not been done before). I could almost do it in 1994 with badly broken templates that barely functioned for pedestrian parameterized types (had to add a line for non-intrusive types to support), but today it's no sweat to match "all types having can_handle as a base class" using enable_if, and void* for those that aren't.
So, my point is that the shared_ptr can be improved in this area, without major changes.
--John
Except that you lose the ability to write code like T t; shared_ptr<T> tp(&t, &nop_deleter); or simply code like T t; if you mandate that anything that inherits enable_shared_from_this should automagically conjure up a shared_ptr on demand. -- Lars Viklund | zao@acc.umu.se
Except that you lose the ability to write code like
T t; shared_ptr<T> tp(&t, &nop_deleter);
or simply code like
T t;
if you mandate that anything that inherits enable_shared_from_this should automagically conjure up a shared_ptr on demand.
-- Lars Viklund | zao@acc.umu.se
My class doesn't have a custom-supplied deleter as a feature. It was not necessary within the implementation to handle base/derived stuff; I guess I approached it in a different way. A class that derives from the special base class is meant to be used as a pointer only. It can't (portably) tell that the instance is not on the heap, and can't tell in general if you aggregated it. Your point is that obtain-smart-pointer-from-this knows that no smart pointer was ever created and it should be an error instead? Certainly, I could have a form that means "give me a smart pointer if it's already in the system, but null if it's not", but I've never needed that. --John TradeStation Group, Inc. is a publicly-traded holding company (NASDAQ GS: TRAD) of three operating subsidiaries, TradeStation Securities, Inc. (Member NYSE, FINRA, SIPC and NFA), TradeStation Technologies, Inc., a trading software and subscription company, and TradeStation Europe Limited, a United Kingdom, FSA-authorized introducing brokerage firm. None of these companies provides trading or investment advice, recommendations or endorsements of any kind. The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.
participants (6)
-
Ganeshram Iyer
-
John Dlugosz
-
Lars Viklund
-
Michael Caisse
-
Ovanes Markarian
-
Ryan McConnehey