使用 MFC 源文件

Microsoft 基础类 (MFC) 库提供完整源代码。 标头文件 (.h) 位于 \atlmfc\include 目录。 实现文件 (.cpp) 位于 \atlmfc\src\mfc 目录

本文介绍 MFC 用来注释每个类各个部分的约定、这些注释的含义以及你在各个部分中可能找到的内容。 Visual Studio 向导使用为你创建的类的相似约定,你可能发现这些约定对自己的代码很有帮助。

你可能很熟悉 publicprotectedprivate 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 类声明的 // Constructors 部分声明构造函数(C++ 意义上)以及真正使用该对象所需的任何初始化函数。 例如,CWnd::Create 位于构造函数部分,因为你使用 CWnd 对象之前,必须先调用 C++ 构造函数再调用 Create 函数,才能“完全构造”该对象。 通常,这些成员是公共的。

例如,类 CStdioFile 包含五个构造函数,其中一个构造函数显示在注释示例下的列表中。

// Attributes 注释

MFC 类声明的 // Attributes 部分包含对象的公共特性(或属性)。 通常,该属性是成员变量或 Get/Set 函数。 “Get”和“Set”函数可能是或可能不是虚拟的。 “Get”函数通常为 const,因为在大多数情况下这些函数没有副作用。 这些成员通常是公共的。 通常可在实现部分中找到受保护属性和专用属性。

注释示例下类 CStdioFile 的示例列表中,列表包含一个成员变量 m_pStream。 类 CDC 在此注释下列出了近 20 个成员。

注意

大型类(如 CDCCWnd)可能具有非常多的成员,因此只是在一个组中列出所有特性并不会大幅提高清晰性。 在这种情况下,类库使用其他注释作为标题来进一步描述这些成员。 例如,CDC 使用 // Device-Context Functions// Drawing Tool Functions// Drawing Attribute Functions 等。 表示特性的组将采用上述常用语法。 许多 OLE 类都具有一个称为 // Interface Maps 的实现部分。

// Operations 注释

MFC 类声明的 // Operations 部分包含的成员函数可供你对对象进行调用以让其执行操作或采取行动。 这些函数通常是非 const 的,因为它们通常具有副作用。 它们可能是虚函数或非虚函数,具体取决于类的需求。 通常,这些成员是公共的。

注释示例下类 CStdioFile 的示例列表中,列表在此注释下包括三个成员函数:WriteString 以及两个 ReadString 重载。

与属性一样,操作也可进一步细分。

// Overridables 注释

MFC 类声明的 // Overridables 部分包含您在需要修改基类行为时可在派生类中重写的虚拟函数。 它们的名称通常以“On”开头,但不是绝对必需的。 此处的函数设计为进行重写,并且一般实现或提供某种“回调”或“挂钩”。通常这些成员是受保护的。

在 MFC 本身中,纯虚拟函数始终放置在此节中。 C++ 中的纯虚函数使用以下形式:

virtual void OnDraw( ) = 0;

注释示例下类 CStdioFile 的示例列表中,列表不包含任何可重写部分。 另一方面,类 CDocument 列出了大约 10 个可重写成员函数。

在部分类中,您还可以查看注释 // Advanced Overridables。 这些只是高级程序员应尝试重写的函数。 你可能从不需要重写它们。

注意

一般而言,本文中描述的约定也适用于自动化(之前称为“OLE 自动化”)方法和属性。 自动化方法类似于 MFC 操作。 自动化属性类似于 MFC 特性。 自动化事件(受 ActiveX 控件(之前称为“OLE 控件”)支持)类似于 MFC 可重写成员函数。

// Implementation 注释

// Implementation 节是任何 MFC 类声明的最重要的部分。

此节存储所有实现详细信息。 成员变量和成员函数都可在此节中出现。 此行下的所有内容在未来版本的 MFC 中都可能会更改。 除非无法避免,否则不应依赖 // Implementation 行下面的详细信息。 此外,在实现行下声明的成员未记录,尽管某些实现在技术说明中讨论过。 无论基类函数是在哪个部分定义,基类中虚函数的重写都位于此部分。 当函数重写基类实现时,它被视为实现详细信息。 通常,这些成员是受保护的,但并不总是这样。

注释示例下的 CStdioFile 列表中,可将 // Implementation 注释下声明的成员声明为 publicprotectedprivate。 请谨慎使用这些成员,因为它们将来可能有所更改。 若要让类库实现正常工作,可能需要将一组成员声明为 public。 但是,这并不意味着可以安全地使用以这种方式声明的成员。

注意

您可以在 // Implementation 注释的上面或下面找到剩余类型的注释。 在任一情况下,这些注释都描述在其下面声明的类型的成员。 如果这些注释出现在 // Implementation 注释下面,则应假设成员在将来版本的 MFC 中可能会更改。

另请参阅

常规 MFC 主题