
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). However, you might want to change the signature of sp_enable_shared_from_this that takes a enable_shared_from_polymorphic_base instead of a enable_shared_from_polymorphic< T >. I tried to just change it but it didn't compile, you might want rearrange your stuff to make it compile and give it a try.
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.
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.