Well, just like the process of creation of a dynamic object can be "disassembled" into two stages: raw memory allocation and actual initialization (e.g. constructor call through placement-new), the process of destroying a dynamic object can also be "disassembled" into two stages: actual de-initialization (destructor call) and raw memory deallocation. (As you can see the the two processes are mirror images of each other.)
This is very useful in situations when you want to use your own raw memory allocation/deallocation mechanism. Granted, in many cases you can achieve the desired effect by overloading operator new/delete
, but in some cases it is not flexible enough and you might prefer to carry out the above steps explicitly.
So, here's one example of when the direct destructor call is a useful feature. There are quite a few others. And yes, it is perfectly legal.
When your class teacher said that you should never do that, he/she probably mean that you should avoid it for now, within the scope of your current curriculum. As you progress in your study, you will understand that many "you should never do that" tricks are actually very useful techniques belonging to "do that, if you know what you are doing" category. Of course, you should not abuse this technique, since it is indeed a low-level one.
P.S. This syntax is formally called pseudo-destructor call, since it sort of allows you to "call" non-existing destructors
typedef int INT;
INT i;
i.~INT(); // <- legal code, pseudo-destructor call, no op
The above is legal C++ code, despite the fact that INT
is not a class type and therefore has no destructor. (Just don't try doing i.~int()
- it is illegal. An aliased typename has to be used for non-class types.)