首页 > 代码库 > 构造函数与析构函数

构造函数与析构函数




本文由 代码助手软件 整理发布 内容与本软件无关 更惬意的读、更舒心的写、更轻松的发布









SDI认知

以前简单的通过向导创建SDI,添加各种功能,未对SDI细节深究,现在借着学习VS2010自带的Ribbon界面的时机,重新审视一番。

一 构造函数 protected类型

class CMainFrame : public CFrameWndEx
{
    
protected: // 仅从序列化创建
    CMainFrame();
    DECLARE_DYNCREATE(CMainFrame)

Doc : public CDocument
{
protected: // 仅从序列化创建
    CTTTDoc();
    DECLARE_DYNCREATE(CTTTDoc)

TView : public CView
{
protected: // 仅从序列化创建
    CTTTView();
    DECLARE_DYNCREATE(CTTTView)
// 特性
public:
    CTTTDoc* GetDocument() const;

声明为保护类型,则不能直接实例化类,之所以这样,是因为MS在APP初始化函数中已经动态实例化了。

默认不能直接实例化CMainFrame,而是在APP的App::InitInstance()中通过RUNTIME_CLASS 动态实例化

    // 注册应用程序的文档模板。文档模板
    // 将用作文档、框架窗口和视图之间的连接
    CSingleDocTemplate* pDocTemplate;
    pDocTemplate = new CSingleDocTemplate(
        IDR_MAINFRAME,
        RUNTIME_CLASS(CTTTDoc),
        RUNTIME_CLASS(CMainFrame),       // 主 SDI 框架窗口
        RUNTIME_CLASS(CTTTView));
    if (!pDocTemplate)
        return FALSE;
    AddDocTemplate(pDocTemplate);

二 析构函数是virtual

// 实现
public:
    virtual ~CMainFrame();

// 实现
public:
    virtual ~CTTTDoc();

// 实现
public:
    virtual ~CTTTView();

原因:析构时先析构子类再析构父类, 因为父类指针可以指向子类对象,如:

void main() 
{ 
  Base* p = new Derived; 
  delete p; 
} 

如果父类析构不是虚函数时,编译器直接将父类析构,而不管子类,如此便会造成子类内存泄露。

而将父类析构函数设置为虚函数后,运行到此时,编译器发现是虚函数,因而会判断出这个指针所指是子类,故而会将子类及其父类析构掉。


构造函数与析构函数