Finaliser and Destructor in C++/CLR and their equivalents in C#
In C# we all know the standard way of finalising an object that potentially contains both managed and unmanaged resources is like
1 class SomeDisposableEntity : IDisposable 2 { 3 #region Constructors 4 5 ~SomeDisposableEntity() // finalizer 6 { 7 Dispose(false); // invoked from finalizer 8 } 9 10 #endregion 11 12 #region IDisposable members 13 14 public void Dispose() 15 { 16 Dispose(true); // invoked from disposing method 17 GC.SuppressFinalize(this); 18 } 19 20 #endregion 21 22 #region Methods 23 24 protected virtual void Dispose(bool disposing) 25 { 26 if (disposing) 27 { 28 // free managed resources if any (use flags to prevent duplicated deallocation) 29 // ... 30 } 31 // free native resources if any (use flags to prevent duplicated deallocation) 32 // ... 33 } 34 35 #endregion 36 37 #endregion 38 }
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
1 class SomeDisposableEntity 2 { 3 !SomeDisposableEntity() // finaliser 4 { 5 // clean up unmanaged resources if any; make sure not to free twice 6 // hence it's similar to C#'s Dispose(false) call 7 // ... 8 } 9 10 ~SomeDisposableEntity() // destructor 11 { 12 // clean up managed resources if any; use flags to avoid freeing twice 13 // hence together with the finaliser call below it's similar to C#'s Dispose(true) call 14 // ... 15 !SomeDisposableEntity(); // destructor always invokes finaliser to clean up unmanaged resources 16 } 17 };
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