In C# we all know the standard way of finalising an object that potentially contains both managed and unmanaged resources is like
class SomeDisposableEntity : IDisposable
{
#region Constructors
~SomeDisposableEntity() // finalizer
{
Dispose(false); // invoked from finalizer
}
#endregion
#region IDisposable members
public void Dispose()
{
Dispose(true); // invoked from disposing method
GC.SuppressFinalize(this);
}
#endregion
#region Methods
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// free managed resources if any (use flags to prevent duplicated deallocation)
// ...
}
// free native resources if any (use flags to prevent duplicated deallocation)
// ...
}
#endregion
#endregion
}
The equivalent C++/CLR looks a bit complicated to C++ programmers, as it introduced the finaliser language feature in addition to the traditional destructor. However to make it simple, we just remember that its finaliser is equivalent to finaliser in C# (with different denotations) and thereby invoked by the garbage collector and C++'s destructor is kind of similar to C#'s Dispose() method responsibility-wise. Therefore note that destructor is normally called before finaliser is called and it's mentioned on MSDN that finalisation of the object is suppressed once the destructor is called, and a typical pattern of writing finalisation code in C++/CLR would be
class SomeDisposableEntity
{
!SomeDisposableEntity() // finaliser
{
// clean up unmanaged resources if any; make sure not to free twice
// hence it's similar to C#'s Dispose(false) call
// ...
}
~SomeDisposableEntity() // destructor
{
// clean up managed resources if any; use flags to avoid freeing twice
// hence together with the finaliser call below it's similar to C#'s Dispose(true) call
// ...
!SomeDisposableEntity(); // destructor always invokes finaliser to clean up unmanaged resources
}
};
References
[1] Destructors and Finalizers in Visual C++, MSDN, http://msdn.microsoft.com/en-us/library/ms177197(v=vs.80).aspx
[2] Implement IDisposable Correctly, MSDN, http://msdn.microsoft.com/en-us/library/ms244737(v=vs.80).aspx