【问题标题】:When a window closes, do my destructors get called?当窗口关闭时,我的析构函数会被调用吗?
【发布时间】:2010-07-23 07:05:11
【问题描述】:

如果窗口关闭(如发送WM_CLOSE),是否会调用对象的析构函数?

在这种情况下,我在源代码后面加上了一个断点,但编译器似乎没有通过我的析构函数。

程序是否在没有调用任何析构函数的情况下关闭?

【问题讨论】:

  • 你有一些代码要显示吗?
  • 如果没有调用析构函数,如您所说,您是否看到应用程序的内存占用异常,从未减少。

标签: c++ visual-c++ winapi destructor


【解决方案1】:

通常不会,除非您的 WindowProc 这样做。

Window 类(例如 ;FC 中的 CWnd 和 ATL 中的 CWindow)是与操作系统的窗口概念不同的实体(我将表示为 HWND)。它们有不同的生命周期,但可以使用 WNDPROC 将它们“耦合”在一起。

IIRC,MFC 会删除 CView 派生类,但不会删除大部分 CWindow 派生类。此外,ATL 的 CWindow 本身不会被破坏,因为默认情况下它只是一个单向附件(即,将 CWindow 附加到 HWND 通常不会子类化窗口)。

大多数时候,调用析构函数是通过另一种机制:

CDialog foo;
foo.DoModal();

当对话框关闭时,将退出声明 foo 的作用域并调用 foos 析构函数。

类似地,关闭主窗口会导致应用程序退出,并以此方式拆除实例。

【讨论】:

    【解决方案2】:

    我不太确定我是否理解,但假设您有一个带有典型 WndProc 的窗口设置,并且您正在使用类似于以下内容的内容发送消息:

    while (GetMessage(&msg, hwnd, 0, 0) > 0)
    { 
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
    

    当窗口结束时(进程WM_DESTROY,在处理WM_CLOSE帖子并调用DestroyWindow之后),此循环将结束,您将继续正常执行。

    换句话说,窗口并没有什么特别之处,但是当它启动时,你几乎陷入了这个循环。你得到与往常一样的清理。

    【讨论】:

      【解决方案3】:

      这取决于关闭窗口后程序的作用。如果它正常退出(通过从main() 返回控制) - 那么是的,析构函数将被调用,但仅限于堆栈分配和全局对象。如果它调用TerminateProcess(),它们肯定不会被调用。

      【讨论】:

        【解决方案4】:

        Windows 中的对象(窗口、对话框、控件等)与程序中包装它们的 C++ 对象是分开的和不同的。关闭的窗口或对话框不会删除程序中恰好通过 m_Hwnd 成员变量与之关联的 C++ 对象。

        用 MFC 术语来说,这样想 - 如果关闭对话框破坏了与其关联的 CDialog 对象,那么您如何检索与(小 d)对话框的控件关联的 CDialog DDX 数据?

        【讨论】:

          猜你喜欢
          • 2012-09-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-15
          • 2011-03-11
          • 1970-01-01
          相关资源
          最近更新 更多