惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - Justin Shen

[.Net 4.0]泛型的协变,以及高阶函数对泛型的影响 Part 1 随笔 - WCF and Data Service - Justin Shen 面向对象语言中的Environment和Binding 元数据 有多少东西需要学习? [电子书下载]Dissecting a C# Application: Inside SharpDevelop [MSDNTV]Don Box再次出击 :) 追踪你的时间使用状况 听说《csdn开发高手》停刊了 在nant中改变编译的目标平台 让使用MSN就像访问网页一样容易! System.String是不可变的字符串吗? 对中国计算机大学教育的一些牢骚 [VS2005]做了两个Code Expansion用的Code Snippet。 VC2005中依然没有Refactoring和Code Expansion. [VS2005 Tip]定制Code Expansion。 [C++/CLI]在栈上声明Reference Type 用80386汇编来编写asp.net页面。 关于C#泛型中的new()约束
[C++/CLI] 析构函数等于IDisposable::Dispose()方法
Justin Shen · 2004-10-14 · via 博客园 - Justin Shen

在以前的一篇帖子里我曾提到在C++/CLI中,会自动调用Dispose()方法。但那个时候只是从msdn上的文章中知道这样一个特性,还没有编译器的支持,所以一切也只能是纸上谈兵,很多细节都很不明朗。VC会以什么样的方式来提供这一特性,一直是我常思考的问题。然而甚至到VS.net 2005 beta1发布时,这一特性还没有得到支持。

好在,在最新的Visual C++ 2005 Tool Refresh中的编译器,已经支持了这一特性。那么就让我们来一探究竟吧。

首先,在最新的编译器中,如果一个类定义了析构函数,编译器会自动让类实现IDisposable接口,并把析构函数映射到Dispose()方法上。假如我们定义以下这个类

它最终生成的IL代码是这样的。

我们可以看到它已经实现了IDisposable接口,并且Dispose方法的内容就是析构函数的内容。

其次为了能够确定自动调用Dispose()方法的时机,C++/CLI现在支持一种新的对象实例化语法。

通常为了获得一个类的实例,我们需要这样写:

Test^ t = gcnew Test();

但为了获得自动调用Dispose()方法的好处,我们必须以这样的语法来实例化类:

Test t;

这就仿佛native c++中在栈(Stack)上实例化了一个对象一样。当然这只是一个语法的模仿,真正的对象还是在堆中实例化的。然而以这种方法实例化,就告诉了编译器,但退出对象申明所在的作用域时,希望能自动调用对象的Dispose()方法。

让我们来看一个函数:

观察函数的IL代码,可以发现调用Dispose()方法的代码已经被加入到方法中了。并且为了在抛出异常时,也能调用Dispose()方法,编译器还自动加上了一个try块。

以上的foo()函数,如果用C#来写,会是这样:

void foo()
{
      using (Test t = new Test())
      {
      }
}

然而,大家都知道using有一个最大的缺点,就是一次只能实例化一个对象。而在ado.net的程序中,经常我们会需要一次申明几个对象。这时候using语句就无能为力了。而C++/CLI提供的这一机制,完美地解决了这一问题。你可以一次申明多个对象,当这些对象退出作用域时,就会自动Dispose。

并且,作用域的识别方法和native c++中是一致的。也就是说你可以添加一对大括号来构成一个作用域,而不一定要是一个函数,就像这样:

值得注意的是,虽然在这个post中,我用了“对象退出作用域”这样的词,但是这只是为了判断Dispose方法调用的时机,并不表明对象在退出作用域之后就被回收了,对象内存的回收仍然是GC操控的,就像C#的using语句中那样。

总得来说,C++/CLI在吸收了C#中using语句的经验与教训之后,为显式释放资源提供了一个完美的解决方案。