当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 删除托管对象,如何果包装一个库?及其它......

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 删除托管对象,如何果包装一个库?及其它......


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 93 ::
收藏到网摘: n/a

C++ Q&A 专栏...
删除托管对象,如何包装一个库?及其它......

原著:Paul DiLascia
翻译:Northtibet

原代码下载:CQA0412.exe (235KB)
原文出处:MSDN Magazine December 2004 (C++ Q&A)

  1. 删除托管对象
  2. 如何包装一个库?

  3. 如何将托管 String 转换回本地的 TCHAR*?

  4. 如何改变标签控件的背景颜色?

在托管 C++ 中,请告诉我使用 delete 操作符销毁托管对象是否安全?

Bernie Sanders
是的,在托管 C++ 中,你可以删除( delete )托管对象,只要你理解删除只不过是调用对象的析构函数,但析构函数必须显示定义。调用 delete 不会释放对象的存储区。只有垃圾收集器才行。Figure 1 展示了一个简单的程序,该程序定义了一个带析构函数的托管类,当它运行的时候会显示一条信息。TESTDTOR 分配两个 ManagedClass 实例。它显式删除第一个实例,但第二个则不然。如果运行 TESTDTOR,你会得到象下面这样的结果:
Begin mainManagedClass(04A712D4)::ctorManagedClass(04A712D4)::dtorManagedClass(04A712E0)::ctorEnd mainManagedClass(04A712E0)::dtor

  它说明了当 delete 语句执行时,第一个对象的析构函数立即执行;而第二个对象(at 04A712E0)则没有被销毁,直到控制离开 main 并且系统终止代码调用垃圾收集器释放逗留对象。


Figure 2 Testdtor 的精彩输出

  不管什么时候,如果你不能确定 .NET 环境中发生了什么,你总是可以编写一些代码,编译它并检查微软中间语言(MSIL)产生的东西。正如 Figure 2 所展示的,定义析构函数导致编译器产生两个方法:一个是 Finalize 方法,它包含你的实现(这里是调用 printf),一个是 __dtor 方法,它调用 System.GC::SuppressFinalize,然后再调用  Finalize。当你删除对象时,编译器产生一个对此 __dtor 方法的掉用。如果你用 /FAs 编译 TESTDTOR 来产生有源码的程序集清单,你将看到 delete 语句以如下的方式编译:

; delete pmc;ldloc.0 ; _pmc$call ??1ManagedClass@@$$FQ$AAM@XZ

奇怪神秘的符号是被修饰过的析构函数(__dtor)。
  老练的 C++ 程序员可能会弄不明白,如果调用 delete 都无法释放对象,那调用它有干什么?好问题。调用 delete 的唯一理由是收回任何你的类所使用的非托管资源。例如,如果你的对象打开数个文件或创建了数据库连接,你可以写一个关闭其资源的析构函数,然后在用完该对象时使用 delete 释放它。在托管类中释放资源的一个更好的方法是通过实现 Dispose 模式,IDisposable——如果你在写托管 C++ 代码——由 auto_dispose 来调用它。(更多的信息参见 Tomas Restrepo 在 MSDN 杂志 2002 二月刊上的文章:“Tips and Tricks to Bolster Your Managed C++ Code in Visual Studio .NET”)。
  如果你实现 dispose 模式,其他的 .NET 使用者也可以使用它。如果你自己在析构函数中进行清理,其它语言便没有办法显式调用你的清理代码。因为在 C# 和 Visual Basic 中没有 delete 操作符。
  所以结果是你能调用 delete 来触发你的析构函数,但是将清理代码放在析构函数中可能不是一个好主意。最好是实现 IDisposable,这样所有人都能使用。注意,在 Visual C++ 2005 中,这个行为有所改变。更多信息参见 Andy Rich 对这个问题的讨论:“Deterministic Finalization IV - Benefits, part II”,以及当前的 C++/CLI 语言规范标准:“C++/CLI Language Specification Standard”

我有一个返回链表的非托管函数,其中有 char* 字符串:

struct blah { int a, b; char *a, *b; struct blah *next;};struct blah *getmystruct();

  因为 getmystruct() 分配内存,当用完之后,我需要调用 freemystruct(struct blah *b)。我尝试做一个包装器,用它来将之转换成托管类型的集合,但我不知道当需要释放所有这些指针的时候,该如何来处理。你能否赐