当前位置:七道奇文章资讯编程技术VC/C++编程
日期: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++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
  • <b>hosts是什么 hosts文件在什么位置 若何改正hosts</b>
  • <b>在 Windows 8 中手动安装语言包</b>
  • <b>五个常见 PHP数据库问题</b>
  • Windows中Alt键的12个高效快速的利用本领介绍
  • <b>MySQL ORDER BY 的实现解析</b>
  • <b>详解MySQL存储历程参数有三种范例(in、out、inout)</b>
  • <b>Win8系统恢复出来经典的开始菜单的办法</b>
  • <b>Win8系统花屏怎么办 Win8系统花屏的办理办法</b>
  • <b>Windows 7系统下无线网卡安装</b>
  • <b>为什么 Linux不需求碎片整理</b>
  • <b>Windows 8中删除账户的几种办法(图)</b>
  • <b>教你如安在win7下配置路由器</b>
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .