日期:2011-03-22 13:56:00 来源:本站整理
<b>C++:最强盛的.NET语言之内存与资源</b>[VC/C++编程]
本文“<b>C++:最强盛的.NET语言之内存与资源</b>[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
当运行环境中包含垃圾回收机制时,辨别开内存管理和资源管理,就非常重要了.典型地来说,垃圾回收器只对包含对象的内存之分配与释放感爱好,它可不关心你的对象能否拥有其他的资源,如数据库衔接或核心对象的句柄.
内存管理
本地C++为程序员供应了超越内存管理的直接掌握本领,在仓库上分配一个对象,意味着只有在进入特定函数时,才会为对象分配内存,而当函数返回或仓库展开时,内存被释放.可以利用操作符new来动态地为对象分配内存,此时内存分配在CRT堆中,并且需求程序员显存地对对象指针利用操作符delete,才能释放它.这种对内存的切确掌握,也是C++可用于编写非常高效的程序的缘由之一,但假如程序员不当心,这也是内存泄露的缘由.另一方面,你不需求告急于垃圾回收器来避免内存泄露--实际上这是CLR所采纳的办法,并且是一个非常有效的办法,当然,关于垃圾回收堆,也有其他一些好处,如改良的分配效率及引用位置相关的上风.全部这一切,都可以在C++中通过库支持来实现,但除此之处,CLR还供应了一个单一的内存管理编程模子,其对全部的编程语言都是通用的,想一想与C++中COM自动化对象相交互和调度数据范例所需做的一切工作,就会发现其重要意义所在--横跨数种编程语言的垃圾回收器,作用是非常宏大的.
为了效率,CLR也保存了仓库的概念,以便值范例可在其上分配,但CLR也供应了一个newobj中间语言指令,以在托管堆中分配一个对象,但此指令只在C#中对引用对象利用操作符new时供应.在CLR中,没有与C++中的delete操作符对应的函数,当利用程序不再引用某对象时,分配的内存最后将由垃圾回收器回收.
当操作符new利用于引用范例时,托管C++也会生成newobj指令,当然,对此利用delete操作符是不合理的.这确切是一个冲突,但同时也证明了为什么用C++指针概念来表示一个引用范例不是一个好的做法.
在内存管理方面,除了上述在对象构造一节谈论过的内容,C++/CLI没有供应任何新的东西;资源管理,才是C++/CLI的特长好戏.
资源管理
CLR只有在资源管理方面,才能赛过本地C++.Bjarne Stroustrup的"资源获得即初始化"的技术概念,基本定义了资源范例的情势,即类的构造函数获得资源,析构函数释放资源.这些范例是被当作仓库上的部分对象,或复杂范例中的成员,其析构函数自动释放先前分配的资源.一如Stroustrup所言"对垃圾回收机制来说,C++是最好的语言,主如果因为它生成很少的垃圾."
大概有一点令人惊奇,CLR并没有对资源管理供应任何显式运行时支持,CLR不支持近似析构函数的C++概念,而是在 .NET Framework中,把资源管理这种情势,晋升到一个IDisposable核心接口范例的中央位置.这种设法源自包装资源的范例,理应实现此接口的单一Dispose办法,以便调用者在不再利用资源时,可调用该办法.没必要说,C++程序员会认为这是时代的倒退,因为他们习惯于编写那些缺省状况下清理就是精确的代码.
因为必必要调用一个办法来释放资源,由此带来的问题是,目前更难编写"全无非常"的代码了.因为非常随时都大概发生,你不大概只是简单地在一段代码后,安排一个对对象的Dispose办法的调用,这样做的话,就必必要冒资源泄露的风险.在C#中办理这个问题的办法是,利用try-finally块和using语句,在面对非常时,可供应一个更坚固的办法来调用Dispose办法.有时,构造函数也会利用这种办法,但普通的情形是,你必必要记着手工编写它们,假如忘掉了,生成的代码大概会存在一个悄无声气的错误.对贫乏真正析构函数的语言来说,能否需求try-finally块和using语句,还有待论证.
using (SqlConnection connection = new SqlConnection("Database=master; Integrated Security=sspi")) { SqlCommand command = connection.CreateCommand(); command.CommandText = "sp_databases"; command.CommandType = CommandType.StoredProcedure; connection.Open(); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { Console.WriteLine(reader.GetString(0)); } } } |
对托管C++来说,情节也非常近似,也需求利用一个try-finally语句,但其是Microsoft对C++的扩大.固然很简单编写一个简单的Using模板类来包装GCHandle,并在模板类的析构函数中调用托管对象的Dispose办法,但托管C++中仍然没有C# using语句的对等物.
Using<SqlConnection> connection(new SqlConnection(S"Database=master; Integrated Security=sspi")); SqlCommand* command = connection->CreateCommand(); command->set_CommandText(S"sp_databases"); command->set_CommandType(CommandType::StoredProcedure); connection->Open(); Using<SqlDataReader> reader(command->ExecuteReader()); while (reader->Read()) { Console::WriteLine(reader->GetString(0)); } |
想一下C++中对资源管理的传统支持,其对C++/CLI也是实用的,但C++/CLI的语言计划犹如为C++资源管理带来了一阵微风.首先,在编写一个管理资源的类时,对大部份CLR平台语言来说,此中一个问题是怎样精确地实现Dispose情势,它可不像本地C++中经典的析构函数那样简单实现.当编写Dispose办法时,需求肯定调用的是基类的Dispose办法--若有的话,别的,假如挑选通过调用Dispose办法来实现类的Finalize办法,还必须关注并发拜候,因为Finalize办法极大概被差别的线程所调用.此外,与正常程序代码相反,假如Dispose办法实际上是被Finalize办法调用的,还需求当心细心地释放托管资源.
C++/CLI并没有与上述情形脱离得太远,但它供应了很多帮忙,在我们来看它供应了什么之前,先来快速回想一下目前的C#和托管C++有多么接近.下例假定Base从IDisposable派生.
class Derived : Base { public override void Dispose() { try { //释放托管与非托管资源 } finally { base.Dispose(); } } ~Derived() //实现或重载Object.Finalize办法 { //只释放非托管资源 } } |
以上是“<b>C++:最强盛的.NET语言之内存与资源</b>[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |
评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论