<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 15.1 內存管理基礎 和大多數的C++程序一樣,你可以在棧上創建對象,也可以在堆上通過new來創建對象.前者的生命周期僅限于其作用范圍,當代碼離開其作用范圍時,對象的析構函數被調用,對象被釋放.而堆上的對象則相反,它將一直存在除非你使用delete操作釋放對象或者整個應用程序退出. 創建和釋放窗口對象 一個通用的規則是:想frame或者按鈕這樣的窗口對象總是應該在堆上使用new方法創建.因為窗口對象通常有一個不確定的生命周期.或者說,窗口對象通常要等用戶決定什么時候關閉并且釋放自己.注意wxWidgets會自動釋放子窗口,因此你只需要調用頂層窗口的Destroy函數,而不需要依次調用窗口中其它控件的Destroy函數.類似的,在被釋放的時候,frame窗口也會自動釋放它的所有的子窗口.不過如果你創建了一個作為 frame窗口子窗口的頂層窗口(比如另外一個frame),這個子窗口將不會被自動釋放.這又有一個例外,在MDI(多文檔界面)中,子文檔窗口將被自動釋放,因為它們其實是主文檔窗口的一部分,是不應該獨立存在的. 你可以在棧上創建對話框窗口,但是它必須是模式對話框.換句話說,你必須使用ShowModal函數使其進入一個事件循環,所有的和用戶的交互都將在這個事件循環中被處理,并且這些交互都發生在對話框離開其作用域從而被釋放之前. 釋放frame窗口和對話框窗口的方法也許讓你感到困惑,我們進一步解釋一下.要釋放frame窗口或者非模式對話框,應用程序應該調用 Destroy函數,這個函數在相關對話框的事件隊列變空以后才會釋放窗口,否則可能將事件發送到不存在的窗口導致程序異常.然而對于模式對話框來說,應該首先調用EndModal函數退出窗口的事件循環.這個函數通常是在對話框的事件處理函數中被調用的,比如默認的OK按鈕事件處理函數.在事件處理函數中只能調用EndModal而不能調用Destroy,因為模式對話框很可能是在棧上創建的,如果在事件處理函數中調用Destroy,很可能導致這個對話框被重復釋放(一次是在事件處理函數中,一次是在棧變量退出其作用域時)導致應用程序表現異常.因此,正確的處理順序是:當用戶點擊關閉按鈕時,產生 wxEVT_CLOSE_WINDOW事件,這個事件的處理函數調用EndModal函數(而不是Destroy函數).而對話框則可以在其退出作用域的時候被自動釋放,這也是所有wxWidgets提供的標準對話框采用的方式.這種方式的另外一個好處在于,當調用EndModal函數退出事件循環以后, 你還可以訪問對話框變量的公共成員以便獲取相應的數據.當然你也可以設計直接在其事件處理函數中釋放自己的對話框,不過對于這種對話框,你就不能夠在棧上創建它并且也不可以在它被關閉以后還可以訪問它的公共成員了. 下面演示的兩種使用wxMessageDialog的方法都是允許的: ``` // 1) 在棧上創建模式對話框,沒有顯式的釋放函數 wxMessageDialog dialog(NULL, _("Press OK"), _("App"), wxOK|wxCANCEL); if (dialog.ShowModal() == wxID_OK) { // 2) 創建在堆上的模式對話框,必須使用Destroy顯式刪除 wxMessageDialog* dialog = new wxMessageDialog(NULL, _("Thank you! "), _("App"), wxOK); dialog->ShowModal(); dialog->Destroy(); } ``` 非模式對話框和frame窗口通常需要在關閉的時候釋放自己,關閉動作可以通過各種方式產生.它們不能在棧上創建,因為它們通常會很快離開自己的作用范圍,將被立即釋放. 如果你使用了指向窗口對象的指針,需要確定在窗口被釋放以后,指針被置為NULL,這可以在窗口的析構函數或者關閉事件處理函數中完成,如下所示: ``` void MyFindReplaceDialog::OnCloseWindow(wxCloseEvent& event) { wxGetApp().SetFindReplaceDialog(NULL); Destroy(); } ``` 創建和復制繪畫對象 繪畫過程中使用的對象,比如wxBrush, wxPen, wxColour, wxBitmap和wxImage等,既可以在堆上創建也可以在棧上創建.這些對象在繪畫函數中使用時通常在棧上創建(局部變量).這些對象內部使用引用記數機制,因此直接使用對象(而不是對象指針)的系統開銷也是非常小的.這種機制的具體作法是:在進行賦值或復制操作的時候,只復制對象內部數據的一個引用而不是整個的內部數據.當然這種機制有時候也會導致一些奇怪的問題,比如某個對象的修改導致所有引用該對象的對象的修改.為了避免這種情況,在需要的時候,你可以通過在構造函數中傳遞具體的參數來構造一個全新的對象.下面各自舉一些例子: ``` // 引用記數 wxBitmap newBitmap = oldBitmap; // 全新拷貝 wxBitmap newBitmap = oldBitmap.GetSubBitmap( wxRect(0, 0, oldBitmap.GetWidth(), oldBitmap.GetHeight())); // 引用記數 wxFont newFont = oldFont; // 全新拷貝 wxFont newFont(oldFont.GetPointSize(), oldFont.GetFamily(), oldFont.GetStyle(), oldFont.GetWeight(), oldFont.GetUnderlined(), oldFont.GetFaceName()); ``` 初始化你的應用程序中的對象 因為你的自定義對象可能先于wxWidgets自己的初始化而被創建,有可能在你的自定義對象初始化的時候,wxWidgets的內部數據包括顏色數據庫,字體數據庫等都還沒有被初始化,因此,不要在你的自定義應用程序類的構造函數中使用wxwidgets的預定義值初始化你的對象,如果你需要使用這些值,可以在OnInit函數中進行.舉例如下: ``` MyApp::MyApp() { // 不要在這個時候作初始化 // m_font = *wxNORMAL_FONT; } bool MyApp::OnInit() { m_font = *wxNORMAL_FONT; ... return true; } ``` 在應用程序退出時執行清理 你可以在重載的wxApp::OnExit函數中執行大多數的清理工作,這個函數是在所有的窗口都已經被釋放,wxWidgets正準備釋放自己的內部數據的時候被調用的.不過有些清理工作還是需要在主窗口的關閉事件處理函數中執行,比如關閉那些可能往主窗口發送數據的進程.
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看