Discussion:
enable_shared_from_this & inheritance
Alex Ott
2006-10-16 09:52:02 UTC
Permalink
Hello all

I have one problem with enable_shared_from_this - i have one Base
class, that inherit from enable_shared_from_this<Base>. But i also
need to do shared_from_this from classes inherited from Base class.
Without explicit inheritance from enable_shared_from_this for Derived
code fail, but when i do enable_shared_from_this<Derived>, my code
fail with "error: reference to 'shared_from_this' is ambiguous"
How i can resolve this issue?
--
With best wishes, Alex Ott
http://alexott.blogspot.com/
http://content-filtering.blogspot.com/
http://xtalk.msk.su/~ott/
Peter Dimov
2006-10-16 13:54:24 UTC
Permalink
Post by Alex Ott
Hello all
I have one problem with enable_shared_from_this - i have one Base
class, that inherit from enable_shared_from_this<Base>. But i also
need to do shared_from_this from classes inherited from Base class.
Without explicit inheritance from enable_shared_from_this for Derived
code fail, but when i do enable_shared_from_this<Derived>, my code
fail with "error: reference to 'shared_from_this' is ambiguous"
How i can resolve this issue?
Your best bet is probably to use dynamic_pointer_cast<Derived>(
shared_from_this() ) in Derived.
Johan Nilsson
2006-10-17 07:34:20 UTC
Permalink
Post by Alex Ott
Hello all
I have one problem with enable_shared_from_this - i have one Base
class, that inherit from enable_shared_from_this<Base>. But i also
need to do shared_from_this from classes inherited from Base class.
Without explicit inheritance from enable_shared_from_this for Derived
code fail, but when i do enable_shared_from_this<Derived>, my code
fail with "error: reference to 'shared_from_this' is ambiguous"
How i can resolve this issue?
Do you mean something like this?

---------

#include <boost/enable_shared_from_this.hpp>

struct A
: boost::enable_shared_from_this<A>
{};

struct B
: A
, boost::enable_shared_from_this<B>
{
boost::shared_ptr<B> FooB()
{
return boost::enable_shared_from_this<B>::shared_from_this();
}

boost::shared_ptr<A> FooA()
{
return boost::enable_shared_from_this<A>::shared_from_this();
}
};

------------

HTH // Johan
Alex Ott
2006-10-17 11:35:40 UTC
Permalink
yes, thanks
Post by Johan Nilsson
Post by Alex Ott
Hello all
I have one problem with enable_shared_from_this - i have one Base
class, that inherit from enable_shared_from_this<Base>. But i also
need to do shared_from_this from classes inherited from Base class.
Without explicit inheritance from enable_shared_from_this for Derived
code fail, but when i do enable_shared_from_this<Derived>, my code
fail with "error: reference to 'shared_from_this' is ambiguous"
How i can resolve this issue?
Do you mean something like this?
---------
#include <boost/enable_shared_from_this.hpp>
struct A
: boost::enable_shared_from_this<A>
{};
struct B
: A
, boost::enable_shared_from_this<B>
{
boost::shared_ptr<B> FooB()
{
return boost::enable_shared_from_this<B>::shared_from_this();
}
boost::shared_ptr<A> FooA()
{
return boost::enable_shared_from_this<A>::shared_from_this();
}
};
------------
HTH // Johan
_______________________________________________
Boost-users mailing list
http://lists.boost.org/mailman/listinfo.cgi/boost-users
--
With best wishes, Alex Ott, MBA
http://alexott.blogspot.com/
http://content-filtering.blogspot.com/
http://xtalk.msk.su/~ott/
Russell Hind
2006-10-18 08:16:57 UTC
Permalink
I thought each time you inherit from enable_shared_from_this<T> you get
a new reference count, so with the code below, won't you end up with 2
separate reference counts to the same instance? I thought this was a
limitation of shared_from_this.

Russell
Post by Johan Nilsson
Do you mean something like this?
---------
#include <boost/enable_shared_from_this.hpp>
struct A
: boost::enable_shared_from_this<A>
{};
struct B
: A
, boost::enable_shared_from_this<B>
{
boost::shared_ptr<B> FooB()
{
return boost::enable_shared_from_this<B>::shared_from_this();
}
boost::shared_ptr<A> FooA()
{
return boost::enable_shared_from_this<A>::shared_from_this();
}
};
------------
HTH // Johan
Johan Nilsson
2006-10-19 13:45:53 UTC
Permalink
Post by Russell Hind
I thought each time you inherit from enable_shared_from_this<T> you
get a new reference count, so with the code below, won't you end up
with 2 separate reference counts to the same instance? I thought
this was a limitation of shared_from_this.
The following passes for me (RC_1_34_0, vc8):

-------
#include <boost/test/auto_unit_test.hpp>
#include <boost/enable_shared_from_this.hpp>

using boost::shared_ptr;
using boost::enable_shared_from_this;

struct A : enable_shared_from_this<A>
{};

struct B : A, enable_shared_from_this<B>
{
shared_ptr<B> FooB()
{
return enable_shared_from_this<B>::shared_from_this();
}

shared_ptr<A> FooA()
{
return enable_shared_from_this<A>::shared_from_this();
}
};

BOOST_AUTO_TEST_CASE(EnableSharedFromThisTest)
{
shared_ptr<B> pB(new B);

BOOST_REQUIRE_EQUAL(1, pB.use_count());

{
shared_ptr<A> pA = pB->FooA();

BOOST_REQUIRE_EQUAL(2, pB.use_count());
BOOST_REQUIRE_EQUAL(pB.use_count(), pA.use_count());
}

BOOST_REQUIRE_EQUAL(1, pB.use_count());
}

-------------

// Johan
Peter Dimov
2006-10-19 16:26:42 UTC
Permalink
Post by Johan Nilsson
Post by Russell Hind
I thought each time you inherit from enable_shared_from_this<T> you
get a new reference count, so with the code below, won't you end up
with 2 separate reference counts to the same instance? I thought
this was a limitation of shared_from_this.
-------
#include <boost/test/auto_unit_test.hpp>
#include <boost/enable_shared_from_this.hpp>
using boost::shared_ptr;
using boost::enable_shared_from_this;
struct A : enable_shared_from_this<A>
{};
struct B : A, enable_shared_from_this<B>
{
shared_ptr<B> FooB()
{
return enable_shared_from_this<B>::shared_from_this();
}
shared_ptr<A> FooA()
{
return enable_shared_from_this<A>::shared_from_this();
}
};
BOOST_AUTO_TEST_CASE(EnableSharedFromThisTest)
{
shared_ptr<B> pB(new B);
I have no idea why this compiles. It shouldn't, B has two
enable_shared_from_this<> bases, and the constructor will only initialize
one of them. Only one of FooA and FooB works (FooA in this case). I'll
investigate.
Peter Dimov
2006-10-19 16:38:30 UTC
Permalink
Post by Peter Dimov
I have no idea why this compiles. It shouldn't, B has two
enable_shared_from_this<> bases, and the constructor will only
initialize one of them. Only one of FooA and FooB works (FooA in this
case). I'll investigate.
The code compiles on g++ and como, but neither FooA nor FooB works. Looks
like an MSVC (and Borland) bug. It would be nice if I could find a way to
make it fail at compile time instead of not working, though...
Nat Goodspeed
2006-10-19 17:16:27 UTC
Permalink
-----Original Message-----
Sent: Thursday, October 19, 2006 12:39 PM
Subject: Re: [Boost-users] enable_shared_from_this & inheritance
Post by Peter Dimov
I have no idea why this compiles. It shouldn't, B has two
enable_shared_from_this<> bases, and the constructor will only
initialize one of them. Only one of FooA and FooB works (FooA in
this
Post by Peter Dimov
case). I'll investigate.
The code compiles on g++ and como, but neither FooA nor FooB works.
Looks
like an MSVC (and Borland) bug. It would be nice if I could find a way
to
make it fail at compile time instead of not working, though...
[Nat] <silly question>
Could the ref count be put into a virtual base class so that only one
instance would appear in a given leaf class, regardless of how many
enable_shared_from_this<> bases it has?
</silly question>
Peter Dimov
2006-10-19 17:34:46 UTC
Permalink
Post by Nat Goodspeed
[Nat] <silly question>
Could the ref count be put into a virtual base class so that only one
instance would appear in a given leaf class, regardless of how many
enable_shared_from_this<> bases it has?
Not a silly question at all.

Every enable_shared_from_this base contains a weak_ptr, not a reference
count. The shared_ptr constructor looks up the enable_shared_from_this base
and initializes its weak_ptr accordingly. This doesn't work when there are
two or more enable_shared_from_this bases, though.

I could put the weak_ptr in a virtual polymorphic base. This would force
polymorphism on all clients of enable_shared_from_this... probably
acceptable. It will also force a dynamic_pointer_cast in every
shared_from_this, and this may be harder to swallow, particularly in cases
where RTTI is off. So I'm not sure.

If you do want the above behavior, it's easy to duplicate, as I already
responded in my first post on the topic. Just make FooB return
dynamic_pointer_cast<B>( FooA() ) and remove the enable_shared_from_this<B>
base (A needs to be made polymorphic, of course).

Continue reading on narkive:
Loading...