There are two ways in C# for safely freeing resources, these are
finally and the
finally enables to call the
Dispose method introduced by the
IDisposable Interface, whereas the
using statement automatically calls it. Both ways ensure that there is no resource leakage in case of an exception. In managed C++, there exists no
using statement. Fortunately, Managed C++ is rich enough to extend itself by using templates. In this article, I will explain something about resource management and how to introduce the
using statement into C++/CLI.
The Common Language Runtime (CLR) is the fundamental part of the .NET Framework and executes the Intermediate Language (IL) code to which all .NET languages are compiled to. Being the base for these languages, it also determines the borders for concepts and features a language is able to provide. Thereby the CLR provides only common functionalities and does not provide resource management out of the box. This would result in a further constraint of all other languages built upon it.
Fortunately, the .NET Framework has introduced a pattern for resource management. This pattern provides the
IDisposable interface. It defines that types which encapsulate resources should provide a
Dispose method to free resources if they are no longer needed.
Unlike C++, C# is a language which does not have the concept of destructors. Therefore it uses
finally and the
using statement to free resources in a reliable and safe manner. This means the resources will be freed despite a thrown exception.
using(DisposableObject MyDisposableObject = new DisposableObject())
using statement creates an object within an own scope. If the execution gets out of scope, the object’s
Dispose-method will be invoked and this results in freeing the resources.
Microsoft extended Managed C++ with the
finally statement, but there exists no
using statement. Now, you probably ask yourself, why do we need
finally when there are destructors?
That is because managed C++ is built upon the CLR and the CLR does not provide the concept of destructors, therefore something magically happens. The language pretends the use of destructors by using the same syntax. When the code gets compiled to IL, the compiler automatically emits the necessary IL code to implement the
Dispose method which serves as a destructor.
As you can see in the picture, the object implements the
IDisposable::Dispose method. This is the reason why it is not legal in C++/CLI to explicitly implement the
Using the Code
Next, I will show you a snippet which introduces the
using statement in C++/CLI. The following template does only one thing; it calls the destructor of some object when the template itself gets destructed.
template <class T> ref class Using
m_Handle = Object;
Before I will explain how it works, I will give an example of how to use it.
Using<DisposableObject> MyDisposableObject(gcnew DisposableObject());
What Happens Here and How Does It Work?
If you execute the example code, an object of the template will be created on the stack. This means, when the execution gets out of the scope, the template object’s destructor gets called. Because of the handle to the
DisposableObject created on the heap, the template object is able to call its
Dispose-method in order to free resources. Because the template object is created on the stack, its destructor will also be called in case of an exception. The brackets around the statement are used to define a scope in C++.
If you compare the two statements between managed C++ and C#, you will recognize the similarity. I propose to download the code snippet for further exploration.
Points of Interest
C++/CLI is for me the almighty .NET language. It gives much freedom by being the low level language for the CLR. Extending the language by using templates does not need much effort. Did you recognize how short the code snippet is?
- 01/07/2009 - Article published