请大侠耐心解决我的问题(关于VC销毁窗口对象),万分感激,谢谢

rfit 2000-04-19 01:25:00
VC 技术内幕(清华) 例子:
在视窗 ( CView ) 内创建了一个非模态对话框,按下鼠标左键显示对话框,
右键关闭。
我在 CmyappView 的构造函数和析构函数中分别设定了
dia=new CmyappDialog(this);
和 delete dia;

在左键消息处理函数中 添加了 dia->Create();
在右键消息处理函数中 添加了 dia->DestroyWindow();
程序运行成功。( 省略了一些步奏 , 如编辑对话框 )

但我有些疑问:
1.DestroyWindow()虽不销毁窗口对象,但它向窗口发送WM_DESTROY和WM_NCDESTROY
引起OnNcDestory(), 由此调用CWnd::PostNcDestroy().
书上说 PostNcDestroy() 将会把窗口对象删除。那么,上面的程序
为什么还要加上delete dia;        是不是我理解错了,请大侠帮助

2.问PostNcDestroy()在用户不加任何代码时,有什么用?
有文章建议:
   void CMyappDialog::PostNcDestroy
   {
   delete this; //删除对象本身
   }
该函数到底是本身就有删除窗口对象的功能,还是本身不能删除窗口对象,但适合在
其函数内加入删除窗口对象的代码,我有些不明白!
   如果把这段代码加入上面的程序中,不在CmyappView 的析构函数中
添加delete dia; 程序运行失败,为什么?
  
...全文
655 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
Akyo 2000-04-23
  • 打赏
  • 举报
回复
PostNcDestroy()在销毁窗口非客户区事件发生时被调用,程序员可以在函数内进行一些需要的处理.但是为什么窗口会销毁呢?当窗口对象的生命周期结束时,或者如上面delete dia代码执行时,PostNcDestroy事件都会激发.
dia不是窗口对象,而是指向一个窗口对象的指针,delete一个指针同时会导致对象的撤销.之所以要delete一个对象是因为:new产生的对象是在'全局堆'上面分配的.例如对于只有在运行的时候才能确定所需内存多少的变量或对象,都可以用new生成.new实际上是向系统申请全局堆的空间,这些空间不属于应用程序而是属于操作系统,delete告诉系统这些空间我再需要了.new和delete总是成对地使用的.
hustwjz 2000-04-21
  • 打赏
  • 举报
回复
我发现你还没有区分指针与对象的区别。
指针总是指向一个内存区域,对于用NEW分配的内存,程序并不会自动删除。你所说的DIA是一个窗口对象,但是他也是一个指向一个内存的指针。
如果你有时间,你可以看一下关于指针的书籍,了解对象在内存中的放置。如果没有时间,你就记着,养成及时删除无用内存是一个程序员的好习惯。
rfit 2000-04-21
  • 打赏
  • 举报
回复
请大侠解决:

“书上说 PostNcDestroy() 将会把窗口对象删除。那么,上面的程序
为什么还要加上delete dia; ”
这个问题。

难道 dia 不是窗口对象??? 谢谢您的帮助      
RiverHill 2000-04-20
  • 打赏
  • 举报
回复
1、有模式窗口与无模式窗口有何区别:明白这点很重要。
有模式窗口会自动创建(在调用了DoModal之后),当用户按了确认和取消键,或者关闭窗口时,会自动销毁。这是因为应用程序此时只能有一个窗口,MFC知道窗口关闭了,就会自动去销毁它,功劳是微软的,缘于MFC封装的好的缘故。
无模式窗口,是动态创建的,在用户按了确认或取消键,或关闭窗口时,并不会自动销毁,所以必须触发事件销毁对话框对象,再手动加上一句delete this;将自己删除掉。

2、dia 是一个指针变量,注意,它只有一个指针变量,指向CmyappDialog。构造函数时new 一个指针,析构时就要delete这个指针,记住,这个delete 只是删除指针。这是代码编写的一般准则,易于维护。

3、每当左鼠单击时,dia在创建一个窗口,即dia->Create();便会在内存中开辟空间,创建一个窗口对象,dia指针指向这个对象。如果,你不停地单击左鼠,程序便会在内存中不断地创建对象,这样,会消耗掉无数的内存空间。如此,你的内存会白白消耗,机器会越来越慢。
4、这时,如果,你不去触发消息去删除对话框,去释放已分配的内存空间,那么,直到你的程序退出之前,这些被分配的内存是不会自动释放的。这种动态创建的对象,只能自己手动去删除。
5、这是右鼠的事件,便是响应这种情况的,触发销毁对象事件,再delete this。
6、你要牢记一点,在VC中凡是动态创建的所有东东,你都得手动去捉来释放,否则,便会造成内存泄露。内存泄露在程序设计中是绝对不允许出现的。如果,用户在使用你的这种软件,动不动内存就被白白占用光了,可以相信,用户下次绝对不会再买了,而改用别人更好的软件了。

7、我觉得,只要理解我以上所讲的,你对CDialog的有模与无模会有初步的了解。
其他的问题,诸如PostNcDestroy().等等这是消息,我建议你会看看相关消息机制的书,消息是有顺序的。

如果还有什么疑问,可给我发Email: RiverHill@263.net
softdoctor 2000-04-19
  • 打赏
  • 举报
回复
有两个问应该搞清楚
1,窗口
2,窗口类

每个窗口在Windows系统中有HANDLE,及其他一些属性,如画刷、风格、窗口函数地址等。
这些属性与该窗口的HANDLE一起构成WINDOWS"窗口对象"。它是由Windows来管理的。

窗口类则是开发工具对窗口对象的封装,他首先是个类,窗口句柄一般是他的成员。
每个窗口类实例化要占用内存,这一内存与窗口对象无关,由程序分配,程序释放。
DestroyWindow(HWND)则从Windows系统删除该窗口对象
Akyo 2000-04-19
  • 打赏
  • 举报
回复
当WM_DESTROY发生时,CView类会析构自身对象,同时它的所有成员变量的析构函数都会被调用.但是对于使用new操作符动态生成的对象,CView类不能自动将其删除,若不使用delete手动删除,会导致内存泄漏,对象的内存没有归还系统.
对于你的另一个问题,我的理解是:delete操作符删除一个对象时会引发对象的析构,在析构函数中调用delete操作,相当于形成一个循环的调用链条,你的程序是否好象死掉了?
如果你另有高见,欢迎赐教.(Akyo007@21cn.com)

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧