新客网
首页 | 新闻 | 系统·网络·服务器·安全 | 工具·办公 | 编程·数据库 | 图象·网页·运营 | 硬件·存储 | 专题教程 | 旧版
 → 当前位置:首页 > 教程 > 编程开发 > C/C#/C++ > 正文

C++:最强大的.NET语言之内存与资源

XKER.COM   2006-5-30 11:03:36  来源:天极  点击:

当运行环境中包含垃圾回收机制时,区别开内存管理和资源管理,就非常重要了。典型地来说,垃圾回收器只对包含对象的内存之分配与释放感兴趣,它可不关心你的对象是否拥有其他的资源,如数据库连接或核心对象的句柄。

  内存管理

  本地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语句的对等物。

本新闻共3页,当前在第1页  1  2  3  

上一篇教程:OpenGL编程轻松入门之背景简介
下一篇教程:C++:最强大的.NET语言之对象构造
收藏本文】 【我要投稿】 【打印本文】 【论坛讨论】 【关闭窗口

相关文章
·实例解析C++/CLI线程之线程状态持久性·C++中class与struct的区别
·Visual C++2005中开发自定义绘图控件·Visual C++实现WinXP关机特效
·VC++中利用/GS开关防止缓冲区溢出·C++中要求(或禁止)对象产生于heap中
·致Delphi和C++Builder社群的一封公开信·C++:最强大的.NET语言之对象构造
·C++数据类型的属性与限制·Visual C++2005中开发自定义绘图控件
·C++的未来之路:C++0x概览·C++/CLI思辨录之代理构造函数
·C++的救赎 C++开源程序库评话·C++多态技术的实现和反思
·保持C/C++程序代码可伸缩性

学院文章搜索
  
推荐文章
·编程过把瘾:自己动手写操
·数据恢复指南 专题
·硬盘“逻辑锁”解决办法
·DOS使用中的常见问题解答
·DOS下常用的相关网络命令
·Win2000优化技巧篇之:硬件
·惊心8小时:破译Windows运行
·菜鸟必备:超实用低级格式
·硬件有价数据无价 硬盘开盘
·国内数据恢复市场内幕揭秘
阅读排行
·免费代理IP(每日更新)
·DB2 9数据库专题
·关于 Apache 的几种常见应
·QQ千人好友浮出水面 会员抢
·佳能活动 免费得QQ秀
·站长手册:WIN2003下Web服
·网站投资你和我的20个自身
·140天,从做站起步到日赚1
·Fdisk分区详解
·超强公式编辑器MathType使
专题教程
·数据恢复指南 专题
·Web服务器专题
·DB2 9数据库专题
·ghost教程 专题
·局域网技术专题
·虚拟机专题
·CDN加速技术专题
·注册表教程专题
·电脑技巧 专题
·Linux与虚拟化技术
最新文章
·Firefox出现新高危0Day漏洞
·QQ千人好友浮出水面 会员抢
·DOS下对系统重新进行分区
·Fdisk分区详解
·DOS常用命令
·dos如何进行系统配置
·dos慎用命令
·Ver、Vol、Ctty命令使用说
·Tree、Unformat、Vsafe命令
·Setver、Share、Subst命令
设为首页 - 加入收藏 - 版权声明 - 广告服务 - 关于我们 - 联系我们 - 友情连接
Copyright © 2003 - 2006 XKER Inc. All Rights Reserved
新客网 版权所有