Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it valid to directly call a (virtual) destructor?

In this answer, Ryan directly calls the virtual destructor. I've tested the code in VS2010, and it correctly calls all destructors (tested with logging statements). Is it actually valid to do so? What are the problems, flaws or even the good points of such an approach?

I can only think of it as a way to really force a reset of the actual type, even if they don't override a virtual reset function, since they atleast have to clean up in their destructors.

Also, eactly what kind of side-effects does a call to the destructor bring? Is it undefined behaviour to use the object after such a destructor call? What if one immediatly reinitializes it with a new (this) MyClass(); call?

like image 366
Xeo Avatar asked May 17 '11 19:05

Xeo


2 Answers

Calling a destructor manually is a perfectly valid thing, regardless of if it's virtual. You just want to make sure that it's just called once for every constructor call.

Is it undefined behaviour to use the object after such a destructor call? 

Yes.

What if one immediatly reinitializes it with a new (this) MyClass(); call?

Still horrifically undefined.

Do not manually destruct an object unless you had to manually place it, e.g. with placement new or some equivalent, and definitely do not ever re-initialize a destructed object like that and hope to avoid UB. Classes like std::vector very explicitly make accessing destroyed objects UB, and it remains UB even if you then make a new element in it's place.

like image 50
Puppy Avatar answered Oct 14 '22 01:10

Puppy


An example of valid use involving one and only one construction:

typedef boost::aligned_storage<
    sizeof(T), boost::alignement_of<T>::value>::type arena_type;
arena_type arena;
T* p = new (&arena) T();
p->~T();
// Don't touch p now

This can be useful when e.g. implementing a variant type (warning: exception-safety left as an exercise to the reader). C++0x unrestricted unions will have similar uses for class types.

Note that for a class type, the above would be UB if you did not call the destructor.

like image 23
Luc Danton Avatar answered Oct 14 '22 00:10

Luc Danton