Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C

The almighty .NET Language - C++/CLI

3.00/5 (3 votes)
1 Jul 2009CPOL3 min read 23.3K   77  
The author shows how easy it is to implement the using statement known by C#.

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.

C#
// C# example of the using statement
 
using(DisposableObject MyDisposableObject = new DisposableObject())
{
    // usage of MyDisposableObject
}

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.

MC++
// C++/CLI realization of the using statement
 
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.

MC++
// C++/CLI usage of the introduced using statement
 
{
   Using<DisposableObject> MyDisposableObject(gcnew DisposableObject());
 
   // usage of MyDisposableObject
   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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)