`
阿尔萨斯
  • 浏览: 4170346 次
社区版块
存档分类
最新评论

WINX窗口类对象的内存管理

 
阅读更多
<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>

WINX窗口类对象的内存管理

许式伟
2006-12-29

为了引入WINX窗口类对象的内存管理(生命周期模型)<wbr></wbr>,我绕了一大圈子。实在是,内存管理太重要了,花多少口舌介绍它都<wbr></wbr>不过分。我曾经见到这样一句话:"C++程序员觉得内存管理太重要<wbr></wbr>了,所以一定要自己进行管理;Java/C#程序员觉得内存管理太<wbr></wbr>重要了,所以一定不能自己去管理"。从某种意义上说<wbr></wbr>,两者都是对的。
我在《C++内存管理变革》系列中提到,我希望C+<wbr></wbr>+程序员理解allocator,并且采用gc allocator(是STL中allocator的延伸)<wbr></wbr>,详细参考前文:
那么WINX的窗口对象是否也是采用gc allocator呢?
答:不是。
具体问题具体分析。在通常情况下,我个人确实已经非常习惯使用gc allocator来进行内存管理,但是WINX窗口对象恰恰是个<wbr></wbr>例外。为什么?原因有二:
  • gc allocator比较适合作为完整应用的解决方案<wbr></wbr>。但是winx只是界面库,由于库的特殊性,它的内存管理也存在一<wbr></wbr>定的特殊性。尽管我喜欢gc allocator,但是我并不能假设所有winx的用户都喜欢g<wbr></wbr>c allocator。
  • winx窗口对象有更加合适且极其简单的内存管理模型。gc和gc allocator的观念,最重要的一点,是要在任意复杂的情形下<wbr></wbr>,提供解决方案来减轻使用者的内存管理负担,它们是从更一般化的角度讨论的方案。但其实聪明的开发人员早已经发明了一种简单有效的<wbr></wbr>手工内存管理法则:基于Owner的内存管理模型。
这种基于Owner的内存管理模型观念非常简单:当一个对象(Child对象)被另一个对象(Owner对象)所拥有,意味着Child对象的生命周期不可能超过Owner对象。因此,Owner对象在自身销毁时,会负责将所有Child对象销毁。
在界面编程中,窗口(指HWND所指代的系统资源)与窗口对象(指C++实现的窗口类实例)的关系是奇妙的。从宏观角度讲,窗口与窗口对象的生命周期是应该是一样的。但是既然它们是两个不同的实例,当然它们的销毁仍然会有细节上的先后之分。在实际应用中,区分为两种完全不同的用况:
  1. 窗口在生成后new出窗口对象(时机一般选择在WM_NCCREATE),并成为窗口对象的Owner。这种用况只有winx支持。它的好处是:
    • 窗口对象的生命周期非常清晰,用户根本无需担心可能发生内存泄漏问题。
    • 支持可视化的自定义窗口的创建方式。详细参考:《WINX如何做到可视化界面开发》。
  2. 窗口对象先于窗口生成,其生命周期完全脱离窗口的生命周期。这是多数界面库的做法。WINX也支持此用法,只要你的窗口类定义了WINX_STACK_OBJECT(TRUE)。它的好处是:
    • 窗口对象可在构造时获得初始化参数,而不需要用丑陋的CreateWindow/CreateWindowEx的额外参数。
    • 对于一个模态过程(例如对话框),窗口对象还可以记录一些返回数据(退出状态)。

如何选择?

在WINX中,方式1.作为默认选择,一般的窗体遵循此模式。而所有顶级窗体(如模态对话框ModalDialog、主窗体MainFrame,MDIMainFrame等)则默认采用方式2.进行管理。我们把这类窗体声明为WINX_STACK_OBJECT,只是因为它们通常声明为栈对象(StackObject),但真实的含义是,窗口对象的生命期脱离窗口,完全由用户自己负责。




分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics