Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode
> _______________________________________________
> Boost-users mailing list
> Boost...@lists.boost.org
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
First of all, if you use fixed_managed_shared_memory, you want to
specify the same base address in ever process, otherwise, you're code
won't work.
You solve your issue, I'm afraid you will need to build a table of
pointers to destructors indexed by a unique number per type (the same
number in all processes), so that when the base class destructor is
called, it makes a lookup in the table and calls the correct
"destructor" function. Not easy, but I think it's the only way. Your
hierarchy couldn't be expanded by users (they need to register their
destructor). It's a limited type of "polymorphism".
Regards,
Ion
Yes, it needs a virtual destructor if it's a shared_ptr to the base
class, otherwise you can't achieve type erasure. This virtual call does
not happen with boost::interprocess::shared_ptr because virtuality is
forbidden in shared memory.
Regards,
Ion
Emil Dotchevski wrote:Yes, it needs a virtual destructor if it's a shared_ptr to the base class, otherwise you can't achieve type erasure. This virtual call does not happen with boost::interprocess::shared_ptr because virtuality is forbidden in shared memory.
You're probably doing something wrong, shared_ptr doesn't require
virtual destructor to call the correct destructor. Here is a working
example: http://codepad.org/sktELTDk
Regards,
Ion
Sorry, I spoke too fast. I was trying to say that if you cast your type
to the base class and they construct a shared_ptr<Base>, then you loose
all your polymorphism. shared_ptr's template constructor does this for
you: shared_ptr ptr only knows the real type of the object in that
constructor and that compile-time information is going to disappear when
the templated constructor ends, so shared_ptr constructs a polymorphic
shared_count that will call the correct deleter when needed:
template<class Y> explicit shared_count( Y * p ): pi_( 0 )
{
//sp_counted_impl_p has VIRTUAL functions
pi_ = new sp_counted_impl_p<Y>( p );
//...
}
sp_counted_impl_p has type Y so it calls Y's constructor and
sp_counted_impl_p is polymorphic so it can be casted to sp_counted_base
without loosing functionality. So you always need virtual functions to
get type erasure with shared_ptr. And that's why you can't do this with
interprocess's shared_ptr.
> Is it really impossible to achieve the same behavior in
> boost::interprocess::shared_ptr than in boost::shared_ptr ?
I afraid you can't. shared memory forbids any type of run-time
polymorphism and that includes shared_ptr.
> PS : By the way, thanks Ion and others for this great work on boost in
> general and the Interprocess library in particular.
Thanks for using Boost in general and Interprocess in particular ;-)
First of all, if you use fixed_managed_shared_memory, you want to specify the same base address in ever process, otherwise, you're code won't work.
You solve your issue, I'm afraid you will need to build a table of pointers to destructors indexed by a unique number per type (the same number in all processes), so that when the base class destructor is called, it makes a lookup in the table and calls the correct "destructor" function. Not easy, but I think it's the only way. Your hierarchy couldn't be expanded by users (they need to register their destructor). It's a limited type of "polymorphism".
You don't have any guarantee that the OS will map it in the same address
in both processes.
> I understand your solution but I don't know wich method I have to redefine.
> Because the problem is not really the destructor, but rather the "deleter".
> And I don't find how to redefine (and register) the base deleter to call
> the derived one.
>
> Could you help me (again...)
Sorry, it was just a fast idea that I haven't elaborated. But I guess
this will be hard to implement. Inheritance and shared memory don't work
very well
> Regards,
> Gaëtan
Gaetan Gaumer wrote:You don't have any guarantee that the OS will map it in the same address in both processes.
First of all, if you use fixed_managed_shared_memory, you want to
specify the same base address in ever process, otherwise, you're
code won't work.
Is it enough to create the segment with the same name in each process :
eg a call to the line below in each process :
fixed_managed_shared_memory segment(open_or_create,"sharedPtrSharedMemoryTest", 2048);
Sorry, it was just a fast idea that I haven't elaborated. But I guess this will be hard to implement. Inheritance and shared memory don't work very well
I understand your solution but I don't know wich method I have to redefine.
Because the problem is not really the destructor, but rather the "deleter".
And I don't find how to redefine (and register) the base deleter to call the derived one.
Could you help me (again...)