万能的 .NET 语言 - C++/CLI





3.00/5 (3投票s)
作者展示了实现 C# 中已知的 using 语句是多么容易。
引言
在 C# 中安全释放资源有两种方法,分别是 try
-finally
和 using
语句。 Try
-finally
允许调用 IDisposable
接口引入的 Dispose
方法,而 using
语句会自动调用它。 这两种方法都能确保在出现异常时不会发生资源泄漏。 在托管 C++ 中,不存在 using
语句。 幸运的是,托管 C++ 足够强大,可以通过使用模板来扩展自身。 在本文中,我将解释一些关于资源管理的内容,以及如何将 using
语句引入 C++/CLI。
背景
公共语言运行时 (CLR) 是 .NET Framework 的基本组成部分,它执行所有 .NET 语言编译成的中间语言 (IL) 代码。 作为这些语言的基础,它也决定了语言能够提供的概念和功能的界限。 因此,CLR 仅提供常见的功能,并且不提供开箱即用的资源管理。 这将导致对所有其他基于它的语言的进一步限制。
幸运的是,.NET Framework 引入了一种资源管理模式。 这种模式提供了 IDisposable
接口。 它定义了封装资源的类型应该提供一个 Dispose
方法,以便在不再需要资源时释放资源。
与 C++ 不同,C# 是一种没有析构函数概念的语言。 因此,它使用 try
-finally
和 using
语句以可靠和安全的方式释放资源。 这意味着即使抛出异常,资源也会被释放。
// C# example of the using statement
using(DisposableObject MyDisposableObject = new DisposableObject())
{
// usage of MyDisposableObject
}
using
语句在自己的作用域内创建一个对象。 如果执行超出作用域,则将调用对象的 Dispose
方法,这将导致释放资源。
Microsoft 使用 try
-finally
语句扩展了托管 C++,但没有 using
语句。 现在,你可能会问自己,当有析构函数时,为什么我们需要 try
-finally
?
那是因为托管 C++ 是建立在 CLR 之上的,而 CLR 没有析构函数的概念,因此会发生一些神奇的事情。 语言通过使用相同的语法来假装使用析构函数。 当代码编译成 IL 时,编译器会自动发出必要的 IL 代码来实现充当析构函数的 Dispose
方法。
正如您在图中看到的那样,对象实现了 IDisposable::Dispose
方法。 这就是为什么在 C++/CLI 中显式实现 Dispose
方法是不合法的。

Using the Code
接下来,我将向您展示一个引入 C++/CLI 中 using
语句的代码片段。 以下模板只做一件事;当模板本身被析构时,它会调用某个对象的析构函数。
// 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;
}
};
在我解释它如何工作之前,我将举一个如何使用它的例子。
// C++/CLI usage of the introduced using statement
{
Using<DisposableObject> MyDisposableObject(gcnew DisposableObject());
// usage of MyDisposableObject
MyDisposableObject->PrintCoolStuff();
}
这里发生了什么以及它是如何工作的?
如果您执行示例代码,将在堆栈上创建一个模板对象。 这意味着,当执行超出范围时,将调用模板对象的析构函数。 由于在堆上创建了 DisposableObject
的句柄,模板对象能够调用其 Dispose
方法以释放资源。 因为模板对象是在堆栈上创建的,所以它的析构函数也会在出现异常时被调用。 语句周围的括号用于定义 C++ 中的作用域。
如果您比较托管 C++ 和 C# 之间的这两个语句,您会认识到它们的相似之处。 我建议下载代码片段以进行进一步的探索。
关注点
对我来说,C++/CLI 是万能的 .NET 语言。 通过成为 CLR 的低级语言,它提供了很大的自由度。 通过使用模板来扩展语言不需要太多的努力。 你有没有注意到代码片段有多短?
历史
- 2009 年 1 月 7 日 - 文章发表