跳轉到內容

更多 C++ 習語/透過初始化附加

來自 Wikibooks,開放書籍,開放世界

透過初始化附加

[編輯 | 編輯原始碼]

在程式執行開始之前將使用者定義的物件附加到框架。

也稱為

[編輯 | 編輯原始碼]
  • 帶有建構函式的靜態物件

某些應用程式程式設計框架,如 GUI 框架(例如 Microsoft MFC)和物件請求代理(例如某些 CORBA 實現)使用自己的內部訊息迴圈(也稱為事件迴圈)來控制整個應用程式。應用程式程式設計師可能或可能沒有自由編寫應用程式級 main 函式。通常,main 函式被埋藏在應用程式框架的深處(例如,MFC 中的 AfxWinMain)。無法訪問 main 使程式設計師無法在主事件迴圈開始之前編寫應用程式特定的初始化程式碼。透過初始化附加習語是一種在框架控制的迴圈開始執行之前執行應用程式特定程式碼的方法。

解決方案和示例程式碼

[編輯 | 編輯原始碼]

在 C++ 中,全域性物件和全域性名稱空間中的靜態物件在 main 開始之前初始化。這些物件也稱為靜態儲存持續時間的物件。靜態儲存持續時間的物件的這一屬性可用於將物件附加到系統,如果程式設計師不允許編寫自己的 main 函式。例如,考慮以下使用 Microsoft Foundation Classes (MFC) 的(最小可能)示例

///// File = Hello.h
class HelloApp: public CWinApp
{
public:
  virtual BOOL InitInstance ();
};
///// File = Hello.cpp

#include <afxwin.h>
#include "Hello.h"
HelloApp myApp; // Global "application" object
BOOL HelloApp::InitInstance ()
{
 m_pMainWnd = new CFrameWnd();
 m_pMainWnd->Create(0,"Hello, World!!");
 m_pMainWnd->ShowWindow(SW_SHOW);
 return TRUE;
}

上面的示例建立了一個標題為“Hello, World!” 的視窗,僅此而已。這裡要注意的關鍵是 HelloApp 型別的全域性物件 myAppmyApp 物件在 main 執行之前被預設初始化。作為初始化物件的副作用,CWinApp 的建構函式也被呼叫。CWinApp 類是框架的一部分,並呼叫框架中其他幾個類的建構函式。在這些建構函式的執行過程中,全域性物件被附加到框架。該物件後來被 AfxWinMain 檢索,它是常規 main 的 MFC 等效項。HelloApp::InitInstance 成員函式僅為完整起見而顯示,不是該習語的必要組成部分。此函式在 AfxWinMain 開始執行後呼叫。

全域性和靜態物件可以通過幾種方式初始化:預設建構函式、帶引數的建構函式、從函式的返回值賦值、動態初始化等。

注意事項

在 C++ 中,同一個編譯單元中的物件按定義順序建立。但是,跨不同編譯單元的靜態儲存持續時間物件的初始化順序沒有明確定義。名稱空間中的物件在訪問該名稱空間中的任何函式/變數之前建立。這可能或可能不在 main 之前。銷燬順序與初始化順序相反,但初始化順序本身沒有標準化。由於這種未定義的行為,當靜態物件的建構函式使用尚未初始化的另一個靜態物件時,會發生靜態初始化順序問題。這種習語很容易陷入這個陷阱,因為它依賴於靜態儲存持續時間的物件。

已知用途

[編輯 | 編輯原始碼]
[編輯 | 編輯原始碼]

參考資料

[編輯 | 編輯原始碼]
  • "透過初始化附加習語的改進可移植性的 C++ 語言擴充套件建議".
華夏公益教科書