Re: Virtual dtor and placement new.
From: Tobias Güntner (fatbull_at_users.sourceforge.net)
Date: 08/16/04
- Next message: Max M.: "Re: Virtual dtor and placement new."
- Previous message: Alf P. Steinbach: "Re: Virtual dtor and placement new."
- In reply to: Giancarlo Niccolai: "Virtual dtor and placement new."
- Next in thread: Giancarlo Niccolai: "Re: Virtual dtor and placement new."
- Reply: Giancarlo Niccolai: "Re: Virtual dtor and placement new."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Mon, 16 Aug 2004 20:23:37 +0200
Giancarlo Niccolai wrote:
> The question is: how to use virtual destructors when dealing with placed
> memory?
Well, you somehow need to remember the type of the object.
My suggestion is the following:
// Basically calls the destructor.
// It is assumed that p is of type T*
template<class T>
void CallDestructor(void* p)
{
static_cast<T*>(p)->~T();
}
typedef void (*DestructPtr)(void*);
// and then replace the placement new with
template<class T>
T* MyNew(void* mem)
{
// Store a pointer to our "destructor"
*static_cast<DestructPtr*>(mem) = CallDestructor<T>;
// Calculate offset to place the object behind the pointer
// TODO: ensure that *newMem is aligned properly!
void* newMem = static_cast<DestructPtr*>(mem) + 1;
// Placement-new the new object as usual
return new(newMem) T;
}
void MyDelete(void* mem)
{
// Now you would call the destructor as follows
(*static_cast<DestructPtr*>(mem))(mem);
}
Note that it is still necessary that you remember a pointer to the
originally allocated object (which can be different, e.g. in the
presence of multiple or virtual inheritance)
It is possible to store this information in a smart-pointer, however.
For example boost::shared_ptr, where you can pass a functor that can do
additional cleanup when the memory is to be deleted (i.e. this functor
could then store a pointer to the original memory and call MyDelete
automatically).
Using a smart pointer seems to be the most reliable way IMHO.
Another approach might be to use thunks (see
http://www.pluralsight.com/articlecontent/cpprep0399.htm for an
example), but that is all very low-level and highly platform dependent.
You could as well derive your object from a special base class that
knows the destructor (works basically like the first approach, but is
not so low-level and more obvious. I guess I should have mentioned this
version first ;) )
struct Deletable
{
virtual void CallMyDestructor() = 0;
};
template<class T>
struct PlacementDeletable : public Deletable, public T
{
virtual void CallMyDestructor() { this->~T(); }
}
Now you have to store a Deletable* somewhere (or you could use
dynamic_cast to get it) and call the destructor through that object.
-- Regards, Tobias
- Next message: Max M.: "Re: Virtual dtor and placement new."
- Previous message: Alf P. Steinbach: "Re: Virtual dtor and placement new."
- In reply to: Giancarlo Niccolai: "Virtual dtor and placement new."
- Next in thread: Giancarlo Niccolai: "Re: Virtual dtor and placement new."
- Reply: Giancarlo Niccolai: "Re: Virtual dtor and placement new."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|