2012-01-31 125 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將刪除該對象。