使用 MFC 原始程式檔
MFC 程式庫提供完整的原始程式碼。 標頭檔 (.h) 位於 \atlmfc\include 目錄中。 實作檔案 (.cpp) 位於 \atlmfc\src\mfc 目錄中。
本文說明 MFC 用來批註每個類別的各個部分、這些批註的意義,以及您應該預期在每個區段中尋找的慣例。 Visual Studio 精靈會針對為您建立的類別使用類似的慣例,而且您可能會發現這些慣例適用于您自己的程式碼。
您可能熟悉 public
、 protected
和 private
C++ 關鍵字。 在 MFC 標頭檔中,您會發現每個類別可能有數個類別。 例如,公用成員變數和函式可能低於一個 public
以上的關鍵字。 這是因為 MFC 會根據其使用來分隔成員變數和函式,而不是根據允許的存取類型。 MFC 會謹慎使用 private
。 即使是考慮實作詳細資料的專案通常是 protected
,而且很多次都是 public
。 雖然不鼓勵存取實作細節,但 MFC 將決定權保留給您。
在 MFC 來源檔案和 MFC 應用程式精靈所建立的標頭檔中,您會在類別宣告中找到類似這些批註的批註(通常依這個順序):
// Constructors
// Attributes
// Operations
// Overridables
// Implementation
註解的範例
下列類別的部分清單 CStdioFile
會使用 MFC 在其類別中使用的大部分標準批註,以使用類別成員的方式來分割類別成員:
/*============================================================================*/
// STDIO file implementation
class CStdioFile : public CFile
{
DECLARE_DYNAMIC(CStdioFile)
public:
// Constructors
CStdioFile();
// . . .
// Attributes
FILE* m_pStream; // stdio FILE
// m_hFile from base class is _fileno(m_pStream)
// Operations
// reading and writing strings
virtual void WriteString(LPCTSTR lpsz);
virtual LPTSTR ReadString(_Out_writes_z_(nMax) LPTSTR lpsz, _In_ UINT nMax);
virtual BOOL ReadString(CString& rString);
// Implementation
public:
virtual ~CStdioFile();
#ifdef _DEBUG
void Dump(CDumpContext& dc) const;
#endif
virtual ULONGLONG GetPosition() const;
virtual ULONGLONG GetLength() const;
virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL);
// . . .
protected:
void CommonBaseInit(FILE* pOpenStream, CAtlTransactionManager* pTM);
void CommonInit(LPCTSTR lpszFileName, UINT nOpenFlags, CAtlTransactionManager* pTM);
};
這些批註會一致標記類別宣告的區段,其中包含類似類別成員的類型。 請記住,它們是 MFC 慣例,而不是設定規則。
建構函式批註
// Constructors
MFC 類別宣告的 區段會宣告建構函式(在 C++ 意義上),以及真正使用 物件所需的任何初始化函式。 例如, CWnd::Create
位於建構函式區段中,因為在您使用 CWnd
物件之前,必須先呼叫 C++ 建構函式,然後呼叫 函式,才能「完整建構」 Create
。 一般而言,這些成員是公用的。
例如,類別 CStdioFile
有五個建構函式,其中一個建構函式會顯示在批註 範例下 的清單。
屬性批註
MFC 類別宣告的 // Attributes
區段包含物件的公用屬性。 屬性通常是成員變數或 Get/Set 函式。 「Get」和「Set」函式不一定是虛擬的。 「取得」函式通常是 const
,因為在大部分情況下,它們不會有副作用。 這些成員通常是公開的。 通常可在實作區段中找到受保護的和私用屬性。
在 類別 CStdioFile
的範例清單中,在批註 範例下 ,清單包含一個成員變數, m_pStream 。 CDC
類別幾乎列出此註解下的 20 個成員。
注意
大型類別 (例如 CDC
和 CWnd
) 可能有許多成員在單一群組中列出所有屬性,但是不會很清楚。 在這種情況下,類別庫會使用其他註解作為標題,進一步描述成員。 例如,CDC
會使用 // Device-Context Functions
、// Drawing Tool Functions
、// Drawing Attribute Functions
等等。 表示屬性的群組會遵循上述的一般語法。 許多 OLE 類別都有稱為 // Interface Maps
的實作區段。
作業批註
// Operations
MFC 類別宣告的 區段包含成員函式,您可以在 物件上呼叫,讓它執行動作或採取動作(執行作業)。 這些函式通常是非的, const
因為它們通常有副作用。 視 類別的需求而定,它們可能是虛擬或非虛擬。 一般而言,這些成員是公用的。
在 類別的範例清單中 CStdioFile
,在批註 範例中 ,此清單包含此批註底下的三個成員函式: WriteString
和 的兩個 ReadString
多載。
如同屬性,作業可以進一步細分。
覆寫的批註
MFC 類別宣告的 // Overridables
區段含有當您需要修改基底類別行為時,您可以在衍生類別中覆寫的虛擬函式。 它們通常會以 「On」 開頭命名,但並非絕對必要。 這裡的函式是設計來覆寫的,而且通常會實作或提供某種「回呼」或「攔截」。一般而言,這些成員會受到保護。
在 MFC 中,純虛擬函式一定會放置在此區段。 C++ 中的純虛擬函式採用下列形式:
virtual void OnDraw( ) = 0;
在 類別 CStdioFile
的範例清單中,在批註 範例中 ,清單不會包含可覆寫的 區段。 另一方面,類別 CDocument
會列出大約 10 個可覆寫的成員函式。
在一些類別中,您也可能會看到 // Advanced Overridables
註解。 這些函式是只有進階程式設計人員應該嘗試覆寫的函式。 您可能永遠不需要覆寫它們。
注意
本文所述的慣例一般而言,也適合用於 Automation (先前稱為 OLE Automation) 方法和屬性。 Automation 方法與 MFC 作業類似。 Automation 屬性類似於 MFC 屬性。 Automation 事件 (支援 ActiveX 控制項,先前稱為 OLE 控制項) 與 MFC 可覆寫成員函式類似。
實作批註
// Implementation
區段是所有 MFC 類別宣告最重要的部分。
此區段包含所有實作詳細資料。 成員變數和成員函式二者可能都會出現在此區段中。 這一行以下的所有內容在 MFC 的未來版本中會有所變更。 除非您無法避免,否則您不應該依賴這一行下方 // Implementation
的詳細資料。 此外,在實作行下方宣告的成員是未記載的,不過有些實作會在技術注意事項中討論。 基類中虛擬函式的覆寫位於本節中,不論基類函式定義于哪一個區段。 當函式覆寫基類實作時,會將其視為實作詳細資料。 一般來說,這些成員是受到保護的,不過並不是始終受保護。
在批 CStdioFile
注範例下的 清單中,批註 下方 // Implementation
宣告的成員可以宣告為 public
、 protected
或 private
。 請謹慎使用這些成員,因為它們未來可能會變更。 將成員群組宣告為 public
可能需要,類別庫實作才能正常運作。 不過,這並不表示您可以安全地使用如此宣告的成員。
注意
您可能會在 // Implementation
註解的上方或下方找到剩餘類型的註解。 不論在上方或下方,它們會均描述在其下宣告的成員類型。 如果它們發生在 // Implementation
註解下,您應該假設成員在 MFC 的未來版本中可能會變更。