0 out of 2 rated this helpful - Rate this topic

4.2 Destructors and operator delete

Visual Studio .NET 2003

A __gc class can have a destructor. During garbage collection, the destructor for a __gc class will be invoked by the common language runtime before the associated memory is released. Following C++ rules, a derived class destructor also calls any base class destructors.

Example

// mcpp_destructors.cpp
// compile with: /clr
#using <mscorlib.dll>
using namespace System;

__gc class Base {
public:
   ~Base() { Console::WriteLine(S"Base::~Base"); }
};

__gc class Derived : public Base {
public:
   ~Derived() { Console::WriteLine(S"Derived::~Derived"); }
};

int main() {
   Derived *d = new Derived();
} // garbage collection is done at program exit

Output

Derived::~Derived
Base::~Base

If a __gc class derives from a __gc class authored in another language, the Finalize method, if any, of the base class is treated as a destructor, and is called automatically at the end of the destructor of the derived class.

An object of a __gc class can only be created by a call to new, which returns a pointer to the object. During execution of a program, the common language runtime deletes unused objects and compacts the runtime heap. The garbage collector will call the destructor of any deleted objects. The order in which destructors are called is unpredictable.

A destructor can be invoked directly by the user or via operator delete. It is equivalent to explicitly calling the destructor as described above (Section 4.2). No memory is freed until a subsequent garbage collection cycle. The destructor will not be called again if the memory for the object is reclaimed during a subsequent garbage collection cycle.

Example

// mcpp_destructors2.cpp
// compile with: /clr /EHsc
#using <mscorlib.dll>
#include <iostream>
using namespace std;

__gc struct G {
   int *p;
   G() { p = new int; }
   ~G() { 
      cout << "G::~G" << endl;
      delete p;
   }
};

int main() {
   G *pG = new G;
   *pG->p = 10;
   pG->~G();   // destructor is called immediately
}

Output

G::~G
Note   As with unmanaged C++ classes, special care should be used when calling destructors directly. If you are not certain that an object is unused, you should let the garbage collector automatically and safely reclaim it.

Characteristic

  • If delete is called on an expression whose compile-time type is pointer to __gc class G, then G shall declare a user-defined destructor.

The programmer can call Finalize on a list of base class pointers.

Example

// mcpp_destructors3.cpp
// compile with: /clr /LD
#using <mscorlib.dll>
using namespace System;

private __gc class ExposeFinalize {
   public: void callFinalize() {
      System::GC::SuppressFinalize(this);
      this->Finalize();
   }
};

static inline void CallFinalize(System::Object *pO) {
   reinterpret_cast<ExposeFinalize*>(pO) -> callFinalize();
}

void destruct_all(Object* base_list[]) {
   for (int i = 0; i < base_list -> Length; ++i) {
      CallFinalize(base_list[i]);
   }
}
Did you find this helpful?
(1500 characters remaining)
© 2013 Microsoft. All rights reserved.