天天看點

MCPP: Destructors in Visual C++ 2008

Re-organized from MSDN documents.

MCPP: Destructors in Visual C++ 2008

Destructors in Visual C++ 2008

Semantics for class destructors have changed significantly from Managed Extensions for C++ to Visual C++ 2008.

In Managed Extensions, a class destructor was permitted within a reference class but not within a value class. This has not changed in the new syntax. However, the semantics of the class destructor have changed.

Before the memory associated with an object is reclaimed by the garbage collector, an associated Finalize method, if present, is invoked. We refer to this as finalization. The timing of just when or even whether a Finalize method is invoked is undefined. This is what we mean when we say that garbage collection exhibits non-deterministic finalization.

Non-deterministic finalization works well with dynamic memory management. When available memory becomes scarce, the garbage collector kicks in. Under a garbage collected environment, destructors to free memory are unnecessary. Non-deterministic finalization does not work well, however, when an object maintains a critical resource such as a database connection or a lock of some sort. In this case, we should release that resource as soon as possible.

[In the native world, that is achieved by using a constructor/destructor pair. As soon as the lifetime of the object ends, either when the local block within which it is declared ends, or when the stack unravels because of a thrown exception, the destructor executes and the resource is automatically released. This approach works very well, and its absence under Managed Extensions was sorely missed. ]

The solution provided by the CLR is for a class to implement the Dispose method of the IDisposable interface. The problem here is that Dispose requires an explicit invocation by the user. This is error-prone. The C# language provides a modest form of automation in the form of a special using statement. The Managed Extensions design provided no special support.

  • Destructors in Managed Extensions for C++
In Managed Extensions, the destructor of a reference class is implemented by using the following two steps:
  1. The user-supplied destructor is renamed internally to Finalize. If the class has a base class (remember, under the CLR Object Model, only single inheritance is supported), the compiler injects a call to its finalizer following execution of the user-supplied code.
  2. In the second step, the compiler synthesizes a virtual destructor. This destructor is what our Managed Extensions user programs invoke either directly or through an application of the delete expression. It is never invoked by the garbage collector.

    Two statements are placed within this synthesized destructor. One is a call to GC::SuppressFinalize to make sure that there are no more invocations of Finalize. The second is the actual invocation of Finalize, which represents the user-supplied destructor for that class.

While this implementation allows the user to explicitly invoke the class Finalize method now rather than at a time you have no control over, it does not really tie in with the Dispose method solution. This is changed in Visual C++ 2008.
  • Destructors in New Syntax

In Visual C++ 2008, the destructor is renamed internally to the Dispose method and the reference class is automatically extended to implement the IDispose interface. That is, under Visual C++ 2008, our pair of classes is transformed as follows:

// internal transformation of destructor under the new syntax

__gc class A : IDisposable {

public:

   void Dispose() {

      System::GC::SuppressFinalize(this);

      Console::WriteLine( "in ~A");

   }

};

__gc class B : public A {

public:

   void Dispose() {

      System::GC::SuppressFinalize(this);

      Console::WriteLine( "in ~B"); 

      A::Dispose();

   }

};

When either a destructor is invoked explicitly under the new syntax, or when delete is applied to a tracking handle, the underlying Dispose method is invoked automatically.

If it is a derived class, a call of the Dispose method of the base class is inserted at the close of the synthesized method.

Destructors and Finalizers in Visual C++

http://msdn.microsoft.com/zh-cn/library/ms177197.aspx

轉載于:https://www.cnblogs.com/DanHL/archive/2009/05/14/MCPPdestructor.html