$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] [smart_ptr] enable_shared_from_this and multiple inheritance solution
From: Ansel Sermersheim (agserm_at_[hidden])
Date: 2010-11-29 22:56:19
Philippe Cayouette <pcayouette_at_[hidden]> writes:
> On 10-11-28 03:02 PM, Ansel Sermersheim wrote:
>> In my solution, my enable_shared_from_polymorphic<T> class is just a
>> shim that inherits virtually from enable_shared_from_polymorphic_base,
>> which is not a template type. The base class holds a weak pointer,
>> which can be dynamic_pointer_cast by the child class when needed.
>
> Interesting idea, you resolve the problem of multiple inheritance with
> virtual inheritance. Having a single internal weak_ptr is surely a
> better idea than having a lot of them.
>> This allows your example to work as expected by merely inheriting from
>> enable_shared_from_polymorphic<T> rather than
>> enable_shared_from_this<T>.
>
> Did you tried your code on GCC? I just applied your patch and I think
> I am encountering the same problem as my example: on GCC, the function
> sp_enable_shared_from_this that is called is the one with the variable
> arguments (...), since the compiler cannot be sure of the value of T
> in the expression enable_shared_from_polymorphic< T > (it might be
> Base1 or Base2). On VS2005, the compiler chooses Base1 (in the
> original example) and thus, the pe->_internal_accept_owner function is
> called on the unique enable_shared_from_polymorphic_base and
> everything works (I guess, I didn't try).
This is rather puzzling. I do develop on GCC, I tested with:
bash$ g++ --version
g++ (Debian 4.4.5-6) 4.4.5
Copyright (C) 2010 Free Software Foundation, Inc.
However, your idea of having the _internal_accept_owner function take
an enable_shared_from_polymorphic base makes perfect sense, and I have
made that change. Hopefully that builds more happily for you.
>> If anyone is interested in the code, it can be found at:
>>
>> http://208.106.110.44/~ansel/boost/enable_shared_from_polymorphic.patch
>>
>> This patch is against the current SVN version of boost.
>>
>> The pro of this method is that the class can be used identically to
>> the way that enable_shared_from_this is used. A downside is that any
>> class deriving from enable_shared_from_polymorphic<T> becomes
>> polymorphic and incurs all the cost thereof.
>
> IMHO, I think the biggest downside of your method is the usage of
> dynamic_pointer_cast, not the polymorphic costs. In fact, dynamic
> casts are non-deterministic and need RTTI, which is not always enabled
> depending on the environment (e.g. VxWorks 653 with cert). Real-time
> applications often disable RTTI to make sure they stay deterministic.
Very good point, and one I often miss since most projects I work on
use RTTI extensively.
>> This cost could potentially be mitigated if these classes used
>> static_pointer_cast instead of dynamic_pointer_cast. However, I am not
>> familiar enough with the appropriate areas of the C++ standard to be
>> sure that would work in cases of multiple inheritance, precisely when
>> these classes are useful.
>
> If you manage to make this work with static_pointer_cast instead of
> dynamic_pointer_cast, it would be the perfect solution to me... but I
> am not sure it is possible.
After mulling this over for some time, I _think_ I have come up with a
solution that mitigates all these problems.
I have a new patch up, at the same URL. In order to make this
mechanism work, I had to add a new constructor to
boost::shared_ptr<T>, which I am loath to do. Given that downside the
patch appears to work properly. It also adds a free function
boost::shared_from<T>(T*) which returns a boost::shared_ptr<T>.
The only cast that occurs in this code is a static_cast that downcasts
from enable_shared_from_polymorphic<T> to T. I have read the relevant
portions of the standard several times and I beleive this is valid,
but I would definitely be curious if wiser heads agree with my reading.
I would be very curious to hear if this new patch compiles
successfully on your system.
Thanks for your feedback,
Ansel