How shared_from_this() work when it inherited from more than one time

please can anyone explain the reason for the following behavior
#include <iostream>
#include

void f(void) { cout << "this is working " << boost::enable_shared_from_this<B>::shared_from_this() << endl; } };
You create an empty enable_shared_from_this<B>, then call shared_from_this() on that one which is of course empty. Intended usage is class B : public A, public boost::enable_shared_from_this<B> { public: B() {} virtual ~B() {} void f(void) { cout << "this is working " << shared_from_this() << endl; // ^^^^^^^^^^^^^^^^^^^^^^ } }; This is not the only error though, Since you're deriving from enable_shared_from_this two times, the above will give an ambiguous call error (did you mean enable_shared_from_this<A> or enable_shared_from_this<B>). Since you're not calling shared_from_this() in A, I suggest you remove enable_shared_from_this<A> altogether. / christian
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Since you're not calling shared_from_this() in A, I suggest you remove
enable_shared_from_this<A> altogether.
But in my case there is no option like this (Class A is a base library
class). So I have to do this.
void f(void)
{
cout << "this is working " <<
boost::enable_shared_from_this<B>::shared_from_this() << endl;
}
};
You create an empty enable_shared_from_this<B>, then call shared_from_this()
on that one which is of course empty.
I did the above to avoid the ambiguous call error
So how can I specify that i am calling the shared_from_this() in class
B....?
On Mon, Aug 10, 2009 at 4:33 AM, Christian Holmquist
void f(void)
{ cout << "this is working " << boost::enable_shared_from_this<B>::shared_from_this() << endl; } };
You create an empty enable_shared_from_this<B>, then call shared_from_this() on that one which is of course empty. Intended usage is
class B : public A, public boost::enable_shared_from_this<B> { public: B() {} virtual ~B() {}
void f(void) { cout << "this is working " << shared_from_this() << endl; // ^^^^^^^^^^^^^^^^^^^^^^ } };
This is not the only error though, Since you're deriving from enable_shared_from_this two times, the above will give an ambiguous call error (did you mean enable_shared_from_this<A> or enable_shared_from_this<B>).
Since you're not calling shared_from_this() in A, I suggest you remove enable_shared_from_this<A> altogether.
/ christian
_______________________________________________ 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
-- Regards, R. P. Janaka

Hello R.P, Inheriting from enable_shared_from_this more than once is not a good idea.
From: boost-users-bounces@lists.boost.org [mailto:boost-users- bounces@lists.boost.org] On Behalf Of R. P. Janaka Sent: Monday, August 10, 2009 6:54 AM To: boost-users@lists.boost.org Subject: Re: [Boost-users] How shared_from_this() work when it inherited from more than one time
But in my case there is no option like this (Class A is a base library class). So I have to do this.
Don't let B inherit from enable_shared_from_this. You've already done that in A. So your question then becomes "how do I retrieve a shared_ptr<B> from this?". Here's how: boost::shared_dynamic_cast(shared_from_this()); In the example you've provided, it would also be safe to use boost::shared_static_cast. To conclude: You should only inherit from enable_shared_from_this in A, and B should only inherit from A.
I did the above to avoid the ambiguous call error So how can I specify that i am calling the shared_from_this() in class B....?
You did. But the problem is that you have two weak_ptrs -- one weak_ptr<A> and one weak_ptr<B> -- and only one of them will be initialized correctly when you create the smart pointer. (If you're interested in debugging your case to really understand what happens, have a look at the function sp_enable_shared_from_this() in shared_ptr.hpp.) Does that help? Cheers, Bjorn Karlsson

Don't let B inherit from enable_shared_from_this. You've already done that in A. So your question then becomes "how do I retrieve a shared_ptr<B> from this?". Here's how:
boost::shared_dynamic_cast(shared_from_this());
Why not: boost::static_pointer_cast<B>(shared_from_this());

Hello Igor,
Why not: boost::static_pointer_cast<B>(shared_from_this());
Yes, inside B (as in the example), static_pointer_cast is the right choice. The same rules apply as for the corresponding C++ casts, so when downcasting, shared_pointer_cast should be used instead. Cheers, Bjorn Karlsson www.skeletonsoftware.net

Yeah.. exactly this is what I wanted to know..
thank you.
2009/8/10 Björn Karlsson
Hello R.P,
Inheriting from enable_shared_from_this more than once is not a good idea.
From: boost-users-bounces@lists.boost.org [mailto:boost-users- bounces@lists.boost.org] On Behalf Of R. P. Janaka Sent: Monday, August 10, 2009 6:54 AM To: boost-users@lists.boost.org Subject: Re: [Boost-users] How shared_from_this() work when it inherited from more than one time
But in my case there is no option like this (Class A is a base library class). So I have to do this.
Don't let B inherit from enable_shared_from_this. You've already done that in A. So your question then becomes "how do I retrieve a shared_ptr<B> from this?". Here's how:
boost::shared_dynamic_cast(shared_from_this());
In the example you've provided, it would also be safe to use boost::shared_static_cast. To conclude: You should only inherit from enable_shared_from_this in A, and B should only inherit from A.
I did the above to avoid the ambiguous call error So how can I specify that i am calling the shared_from_this() in class B....?
You did. But the problem is that you have two weak_ptrs -- one weak_ptr<A> and one weak_ptr<B> -- and only one of them will be initialized correctly when you create the smart pointer. (If you're interested in debugging your case to really understand what happens, have a look at the function sp_enable_shared_from_this() in shared_ptr.hpp.)
Does that help?
Cheers, Bjorn Karlsson
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Regards, R. P. Janaka

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Monday 10 August 2009, Björn Karlsson wrote:
Don't let B inherit from enable_shared_from_this. You've already done that in A. So your question then becomes "how do I retrieve a shared_ptr<B> from this?". Here's how:
boost::shared_dynamic_cast(shared_from_this());
The shared_*_cast names are deprecated according to shared_ptr.hpp. They are spelled *_pointer_cast now. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkqAF/EACgkQ5vihyNWuA4VqFgCeO+XJhSihS1m+vxsDY0niQeEW 8LsAniPa51EYxc+dcwiI0ZdNndHsi9Wn =KWJb -----END PGP SIGNATURE-----

Hello Frank,
The shared_*_cast names are deprecated according to shared_ptr.hpp. They are spelled *_pointer_cast now.
You're right, thanks for the reminder. The rationale for this name change can be found in the smart pointer proposal, N1540: "The cast operations were originally named shared_static_cast and shared_dynamic_cast in the Boost implementation, but it soon became clear that other smart pointer types can (and should) provide the same functionality, preferably in a generic manner, and the functions were renamed to *_pointer_cast to indicate wider applicability." Cheers, Bjorn Karlsson www.skeletonsoftware.net
participants (5)
-
Björn Karlsson
-
Christian Holmquist
-
Frank Mori Hess
-
Igor R
-
R. P. Janaka