In C + +, it is convenient to dynamically allocate memory through operator new and delete, where the default semantics of new is to allocate memory and call the constructor, while the default semantics of delete is to call the destructor and free memory, noting that both operators deal with pointers, And when it comes to pointers things are a little complicated, let's look at an example:
Class A {public:~a () {cout<< "destructor of a" <<endl;}}; Class B:public A {public:~b () {cout<< "destructor of B" <<endl;}}; int main () {A *p = new B ();d elete P;return 0;}
In this example, B inherits from a, so a pointer can point to B, in main () we dynamically create a B object, and point to it with a pointer, when we do not need this object, we should call the destructor of B and release the corresponding memory, so directly delete p, So what about the output?
destructor of A;
Only a destructor is called, so if we have some memory-freeing operations in the destructor of B, then these memory-freeing operations will not be executed, causing a memory leak, because the compiler thinks the delete is followed by a static pointer, so it will be based on the type of P The compile time determines which destructor is called, in this case p is a pointer of type A, so A's destructor is called. The way to avoid this problem is to use a virtual destructor, as follows:
#include <iostream>using namespace Std;class a {public:virtual ~a () {cout<< "destructor of a" <<endl;}} ; class B:public A {public:~b () {cout<< "destructor of B" <<endl;}}; int main () {A *p = new B ();d elete P;return 0;}
In this example, A's destructor is decorated with virtual, meaning that the class and a derived from a have virtual destructors, virtual destructors are virtual functions, so the C + + dynamic binding mechanism is used, so when the delete p, the compiler found that p although is a type, but a has a virtual destructor , so it does so by placing the code in the calling mechanism of the virtual function toImplementation PeriodCall the destructor of the object that p really points to, so we can finally find the destructor of B at execution time, and the result is as we expected: first call the destructor of B, then call the destructor of base class A.
destructor of B;
destructor of A;
C + +: Delete and memory leaks