1.MFC程序中类的开始

化简:

MFC对话框程序最少包含一个从CWinApp派生的类(这个类负责应用程序的初始化、运行和终止),必须重写 InitInstance 方法来进行应用程序的初始化。

如果你的应用程序包含对话框,那么通常会从CDialogEx(或其前身CDialog)派生一个类。

virtual关键字用于指定一个成员函数在基类中被重写。

======================================================================

在Microsoft Foundation Classes (MFC)程序中,至少会包含几个关键的类,但具体包含哪些类取决于应用程序的类型。

以下是MFC对话框程序中通常包含的一些基本组件:

  1. CWinApp:这是MFC应用程序的基类,每个MFC应用程序都必须有一个从CWinApp派生的类。这个类负责应用程序的初始化、运行和终止。

  2. CDialogEx:这是MFC中用于创建对话框的基类。如果你的应用程序包含对话框,那么通常会从CDialogEx(或其前身CDialog)派生一个类。

以下是MFC单文档界面(SDI)或多文档界面(MDI)应用程序通常包含的几个基本类:

  • CMainFrame:这是主框架窗口的类,通常从CFrameWnd或其派生类(如CMDIFrameWndCFrameWndEx)派生。

  • CView:这是视图类的基类,用于显示和操作文档数据。

  • CDocument:这是文档类的基类,用于管理应用程序的数据。

以下是一个简单的MFC SDI应用程序可能包含的类的例子:

class CMyApp : public CWinApp {
public:
    virtual BOOL InitInstance();
};

class CMainFrame : public CFrameWnd {
    // ...
};

class CMyView : public CView {
    // ...
};

class CMyDoc : public CDocument {
    // ...
};

class CMyDialog : public CDialogEx {
    // ...
};

在这个例子中,CMyApp 是应用程序类,它必须重写 InitInstance 方法来进行应用程序的初始化。CMainFrame 是主框架窗口类,CMyView 是视图类,CMyDoc 是文档类,而 CMyDialog 是一个对话框类。

因此,一个基本的MFC程序至少包含一个从 CWinApp 派生的应用程序类,如果程序中有对话框,则至少包含一个从 CDialogEx 派生的对话框类。但通常还会有其他几个类来构成应用程序的框架。

 

======================================================================

在C++中,virtual关键字用于指定一个成员函数在基类中被重写,这样它就可以在派生类中被重新定义,并且表现出多态的行为。以下是一些使用virtual关键字的情况:

  1. 多态性:当你想要通过基类指针或引用调用派生类中的函数时,你应该在基类中将该函数声明为virtual。这样,即使指针或引用的类型是基类类型,调用的也会是派生类中重写的版本。

  2. 继承:在继承中,如果你希望派生类能够覆盖(override)基类中的某个函数,你应该在基类中将该函数声明为virtual

  3. 虚析构函数:如果你有一个基类,它将被用作继承的起点,并且该基类有需要释放的资源(如动态分配的内存),你应该提供一个virtual析构函数。这样,当通过基类指针删除派生类对象时,可以确保正确的析构函数链被调用,从而防止资源泄漏。

以下是一些具体的使用场景:

  • 基类定义接口:当你定义一个基类,它提供了通用的接口,而不同的派生类将提供具体的实现时。

  • 工厂模式:在实现工厂模式时,你通常会定义一个基类,其中包含一个或多个virtual函数,然后通过派生类来创建具体的对象。

  • 观察者模式:在观察者模式中,virtual函数可以用来通知观察者对象状态的变化。

  • 策略模式:在策略模式中,不同的算法可以在派生类中实现,并通过基类的virtual函数来调用。

以下是一个简单的例子,展示了如何使用virtual关键字:

class Base {
public:
    virtual void DoSomething() {
        // 基类的实现
    }
    
    virtual ~Base() {
        // 虚析构函数
    }
};

class Derived : public Base {
public:
    void DoSomething() override {
        // 派生类的实现,覆盖基类的DoSomething
    }
};

int main() {
    Base* b = new Derived();
    b->DoSomething(); // 调用Derived类的DoSomething方法
    delete b; // 正确地调用Derived类的析构函数,然后是Base类的析构函数
    return 0;
}

在这个例子中,DoSomething在基类中被声明为virtual,因此在派生类中可以重写它。同样,基类的析构函数也是virtual的,确保了通过基类指针删除派生类对象时能够正确地调用析构函数链。

posted @   流水江湖  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示