Introduction
There are two ways in C# for safely freeing resources, these are try
-finally
and the using
-statement. Try
-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.
Background
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 try
-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())
{
}
The 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 try
-finally
statement, but there exists no using
statement. Now, you probably ask yourself, why do we need try
-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 Dispose
method.
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
{
private:
T^ m_Handle;
public:
Using(T^ Object)
{
m_Handle = Object;
}
T^ operator->()
{
return m_Handle;
}
~Using()
{
delete m_Handle;
}
};
Before I will explain how it works, I will give an example of how to use it.
{
Using<DisposableObject> MyDisposableObject(gcnew DisposableObject());
MyDisposableObject->PrintCoolStuff();
}
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?
History
- 01/07/2009 - Article published