MFC开发过程中起始有很多的细节指出可以作为一种模式,为今后的MFC开发工作做实际指导。本文介绍无模式对话框的内存管理。
l 五号宋体斜字体表示:特定定义;
l 小五号Arial字体表示:VC++代码使用
l 五号楷体字体表示:类名称、类对象
无模式对话框即Modeless Dialog。之所以称为无模式,是因为无模式对话框允许用户同时操作其他窗口,这样窗口就可以作为工具窗口在程序主要窗口之外提供额外的功能,分离了各个对话框的功能。最常见的是Windows操作系统层次的窗口,例如资源管理器,我的电脑,Word等。本文介绍的是更下一层次的窗口,例如Word的属性设置对话框。
无模式对话框的创建通过“三步曲”完成:new -> CreateWindow() -> ShowWindow(SW_SHOW)。无模式对话框的销毁通常有两种方法,一是在对话框的OnNcDestroy()函数中用delete this销毁自身内存,二是在外界用delete pdlg来清空内存。一下我们简称第一种方法为自销毁方法,称第二种方法为外销毁方法。
事实上两种方法创建的对话框的使用方式完全相同。他们的不同之处仅在于内存由谁来负责回收。
面向对象的C++的基本内存管理思想是由对象自身负责内存的回收,类的构造函数和析构函数正是这种思想的直接实现者。构造函数中应该包含所有对象中内存的分配逻辑,析构函数中包含所有对象中内存的释放逻辑。这样,不管对象中包含了如何复杂的内存存储结构,外界的管理方法都一样简单:对于静态对象,只需简单的对象声明即可,而对于动态对象,调用new/delete,就可以为对象分配/回收内存。
但关键问题是C++的指针特性带来了问题。指针特性带来了动态内存分配能力,但它是一把双刃剑,大部分的内存泄漏都与此有关。对于静态对象,构造和析构对象的代码都被作为可执行文件的一部分硬性编译到了可执行文件中,应用程序肯定会执行这一段代码,内存肯定不可能泄漏(除非系统有不测风云)。而动态对象必须由程序员负责调用delete来手动销毁,这是问题的关键所在,许多粗心的程序员常常会因为忘记了调用delete而导致内存泄漏而为此感到痛心疾首,或者因为多调用了delete后出现了严重的异常导致程序崩溃。我对那个Windows下的画着红色X号对话框是如此的记忆深刻,甚至我一看见他就觉得心惊胆战、浑身不爽。
如果你使用具有自销毁能力的对话框类创建模式对话框,你也同样将不得不面对这样的问题,那个红色X号对话框就会象恶魔一样缠着你。模式对话框使用DoModal()函数创建Windows窗口,在DoModal()返回的过程中,MFC 框架将发送NC_DESTROY消息到窗口,窗口在接受到该消息后执行窗口类的OnNcDestroy()函数。由于该类应用了自销毁方法,此时将调用delete this