2012-01-31 122 views
2

如果我试图定义一个GUI按钮CButton的像CButton btn;我得到一个错误 - >因为我试图把它的堆栈为什么许多GUI CObjects(即CButton)必须放在堆上,而不是堆栈?

上,但如果我这样做CButton *btn = new CButton();它的工作原理,这被放在堆。

为什么我不能把CButton对象放在堆栈上?

+0

你在使用什么库?这些CButton对象来自哪里?这是MFC还是其他的东西?你收到什么错误? – 2012-01-31 20:40:00

+2

这个决定不是关于堆或堆栈。它关于存储时间,可能是多态。另外,避免使用这种“裸”的“新”,因为它很容易导致内存泄漏和其他问题。 – 2012-01-31 20:42:53

回答

3

这是一个存储期限问题。使用MFC,CButton的目的是让用户可以点击它,这会生成一个事件,然后您可以处理。所有这些都表明CButton的生命周期必须超出创建它的函数的生命周期。在一个典型的MFC对话框类(CDialog)中,CButton是一个成员变量,所以它的生命周期是类实例的生命周期。如果您改为在构造函数中声明CButton变量,它将超出范围并在构造函数结束时被销毁。

有一些不寻常的情况,您可能想根据直到运行时才知道的决定来创建按钮。在这种情况下,上述关于不使用裸“新”的评论很重要。使用智能指针(或智能指针的容器)来保存您创建的CButton *,以便它们自动清理。这些智能指针或容器需要在类作用域创建。

+0

请注意,许多这些窗口包装类的析构函数不一定会删除本机窗口。 MFC世界中的C++对象创建和Windows对象创建不等效。 – 2012-02-01 01:51:38

1

我不知道MFC,但我的猜测是,你的CButton,它被分配在堆栈上超出范围,从而被销毁。
从其他地方访问此按钮的实例将导致访问冲突。

1

1)其他许多人已经回复,它必须处理变量的范围。通过使函数处于本地位置,当函数退出时它将结束它的生命。

2)堆栈空间比堆空间有限得多,特别是对于多线程。典型的win32进程的堆栈分配少于1兆字节,但可以有数千兆字节的堆。

4

在MFC中有一个常见的习惯用法,我没有在其他地方见过。可以创建一个将被自动清理的“临时”对象。清理发生在MFC处理的某些阶段,例如消息循环。

CButton * btn = (CButton *) FromHandle(hwnd); 

FromHandle函数返回一个指向CWnd对象,但你不知道该对象是从哪里来的。你不应该尝试删除指针,并且不要依赖指针超出当前范围有效 - 永远不要将它保存到成员变量!如有必要,MFC将删除该对象。