记得老师说过创建CView的时候使用new的方式,不要使用类 对象;这种方式??

yangxuefeng09 2014-06-19 10:04:27
记得看视频的时候老师说过 创建CView的时候,也就是创建视图的时候,不要使用 Cview m_view;这种方式

而是使用Cview * pView=new Cview();这种方式 。因为窗口在关闭的时候会调用一个叫做PostNCDestory()的函数,

这个函数的最后一句话是delete this;所以就会导致一种现象 因为使用 Cview m_view;进行构造了,

窗口关闭的时候就会调用析构函数。而关闭过程一定会执行PostNCDestory()函数时候又 delete this;


释放掉了一次。就会导致一块内存释放掉了两次的效果。所以就会出错。


但是今天看 VC向导创建出来的没有Document支持的 单个窗口的时候,突然发现里面有这样的一句话:

protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
CChildView m_wndView;
这里面的第三句话不就是使用CChildView m_wndView;类 对象;方式创建的吗?????

那么为什么这个时候不会出现错误??????

是因为PostNCDestory()函数这个函数被重写了吗???

还是因为什么原因那????
...全文
247 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
图灵转世 2014-06-20
  • 打赏
  • 举报
回复
研究的真深入,长见识了。学习中。
信阳毛尖 2014-06-20
  • 打赏
  • 举报
回复
老师说这里不能写成CMyView m_pwndView; (类 对象;)这种方式 因为在PostNcDestory()函数中有一个 delete this;语句,所以为了防止内存释放掉两次 这里不能使用CMyView m_pwndView;而必须使用 CMyView * m_pwndView; 但是为什么在MFC使用向导创建出来的程序中就是用了 : protected: // control bar embedded members CStatusBar m_wndStatusBar; CToolBar m_wndToolBar; CChildView m_wndView; ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- 你知道为什么CView类的虚函数PostNcDestory()函数中有一个delete this吗? 正如我前面所说的:CView 在MFC文档视图框架下是通过RunTime动态创建的,因此就需要自删除,否则删除工作由程序员来操作会带来很大的麻烦和漏洞! 然而你的这个程序基本上是根据MFC文档视图框架原理自写的一个简单框架程序,与MFC文档视图框架相差甚远:view不是RunTime动态创建的,且不是多文档视图的,只有一个view,并且都是自行处理。 CChildView m_wndView; 关于这个,你需要检查一下CChildView 类中是否重载了PostNcDestory()并delete this
lis2012 2014-06-20
  • 打赏
  • 举报
回复
引用 3 楼 yangxuefeng09 的回复:
[quote=引用 1 楼 lsq19871207 的回复:] CView 在MFC文档视图框架下是通过RunTime动态创建的(不需要开发人员手动new)
// MFCView.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

class CMyView : public CView
{
public:
    virtual void OnDraw( CDC* pDC );
 
    DECLARE_MESSAGE_MAP( )
public:
    afx_msg void OnPaint( );
    afx_msg void OnTest( );
};

BEGIN_MESSAGE_MAP( CMyView, CView )
    ON_WM_PAINT( )
 ON_COMMAND( ID_TEST, OnTest )
END_MESSAGE_MAP( )

void CMyView::OnTest( )
{
    AfxMessageBox( "OnTest" );
}


void CMyView::OnPaint( )
{
    PAINTSTRUCT ps = { 0 };
    HDC hDC = ::BeginPaint( m_hWnd, &ps );
    TextOut( hDC, 100, 100, "View", 4 );
    ::EndPaint( m_hWnd, &ps );
}

void CMyView::OnDraw( CDC * pDC )
{
 pDC->TextOut( 100, 100, "Hello View");
}

class CViewFrame : public CFrameWnd
{
public:
    CViewFrame( );

    virtual BOOL OnCmdMsg( UINT nID, int nCode, 
        void* pExtra, 
        AFX_CMDHANDLERINFO* pHandlerInfo );
       

    DECLARE_MESSAGE_MAP( )
public:
    afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct );

public:
    CMyView * m_pwndView;
//*请看这里,我们创建View的时候使用的是指针方式。没有采用     (类    对象;)方式。
老师说这里不能写成CMyView     m_pwndView;  (类    对象;)这种方式   因为在PostNcDestory()函数中有一个
delete   this;语句,所以为了防止内存释放掉两次  这里不能使用CMyView     m_pwndView;而必须使用  
CMyView * m_pwndView;   但是为什么在MFC使用向导创建出来的程序中就是用了 :
protected:  // control bar embedded members
CStatusBar     m_wndStatusBar;
CToolBar    m_wndToolBar;
CChildView    m_wndView;
我们可以看到:
CChildView    m_wndView;这种方式  为什么这种方式可以??????????????
*/

};

BEGIN_MESSAGE_MAP( CViewFrame, CFrameWnd )
    ON_WM_CREATE( )

END_MESSAGE_MAP( )

CViewFrame::CViewFrame( )
{
    m_pwndView = NULL;
}

int CViewFrame::OnCreate(LPCREATESTRUCT lpCreateStruct )
{
    CFrameWnd::OnCreate( lpCreateStruct );
    //View对象
    m_pwndView = new CMyView( );
    //创建View
    m_pwndView->Create( NULL, "View",
        WS_CHILD|WS_VISIBLE|WS_BORDER, 
        CRect( 100, 100, 200, 200 ),
        this, AFX_IDW_PANE_FIRST );

     SetActiveView( m_pwndView );

    //ModifyStyle( WS_BORDER )
    ModifyStyleEx( WS_EX_CLIENTEDGE, 0 );

    return 0;
}

BOOL CViewFrame::OnCmdMsg( UINT nID, int nCode, 
        void* pExtra, 
        AFX_CMDHANDLERINFO* pHandlerInfo )
{
      if( NULL != m_pwndView )
    {
        if( TRUE == m_pwndView->OnCmdMsg( nID,
            nCode, pExtra, pHandlerInfo ) )
        {
            return TRUE;
        }
    }

  
    return CFrameWnd::OnCmdMsg( nID, nCode,
        pExtra, pHandlerInfo );
}


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

CViewApp theApp;

BOOL CViewApp::InitInstance( )
{
    CViewFrame * pWnd = new CViewFrame( );
    pWnd->Create( NULL, "ViewApp",
        WS_OVERLAPPEDWINDOW,
         CFrameWnd::rectDefault, NULL,
        MAKEINTRESOURCE( IDR_MAINFRM ) );
    m_pMainWnd = pWnd;
    m_pMainWnd->ShowWindow( SW_SHOW );
    m_pMainWnd->UpdateWindow( );
    return TRUE;
}


[/quote] 销毁cmyview的代码在哪里
yangxuefeng09 2014-06-20
  • 打赏
  • 举报
回复
引用 7 楼 lsq19871207 的回复:
老师说这里不能写成CMyView m_pwndView; (类 对象;)这种方式 因为在PostNcDestory()函数中有一个 delete this;语句,所以为了防止内存释放掉两次 这里不能使用CMyView m_pwndView;而必须使用 CMyView * m_pwndView; 但是为什么在MFC使用向导创建出来的程序中就是用了 : protected: // control bar embedded members CStatusBar m_wndStatusBar; CToolBar m_wndToolBar; CChildView m_wndView; ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- 你知道为什么CView类的虚函数PostNcDestory()函数中有一个delete this吗? 正如我前面所说的:CView 在MFC文档视图框架下是通过RunTime动态创建的,因此就需要自删除,否则删除工作由程序员来操作会带来很大的麻烦和漏洞! 然而你的这个程序基本上是根据MFC文档视图框架原理自写的一个简单框架程序,与MFC文档视图框架相差甚远:view不是RunTime动态创建的,且不是多文档视图的,只有一个view,并且都是自行处理。 CChildView m_wndView; 关于这个,你需要检查一下CChildView 类中是否重载了PostNcDestory()并delete this
好的 前辈 我去看看这个函数是否被重载了,估计是重载了把delete this;这句删除了吧 我去看看
yangxuefeng09 2014-06-20
  • 打赏
  • 举报
回复
引用 6 楼 lis2012 的回复:
[quote=引用 3 楼 yangxuefeng09 的回复:] [quote=引用 1 楼 lsq19871207 的回复:] CView 在MFC文档视图框架下是通过RunTime动态创建的(不需要开发人员手动new)
// MFCView.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

class CMyView : public CView
{
public:
    virtual void OnDraw( CDC* pDC );
 
    DECLARE_MESSAGE_MAP( )
public:
    afx_msg void OnPaint( );
    afx_msg void OnTest( );
};

BEGIN_MESSAGE_MAP( CMyView, CView )
    ON_WM_PAINT( )
 ON_COMMAND( ID_TEST, OnTest )
END_MESSAGE_MAP( )

void CMyView::OnTest( )
{
    AfxMessageBox( "OnTest" );
}


void CMyView::OnPaint( )
{
    PAINTSTRUCT ps = { 0 };
    HDC hDC = ::BeginPaint( m_hWnd, &ps );
    TextOut( hDC, 100, 100, "View", 4 );
    ::EndPaint( m_hWnd, &ps );
}

void CMyView::OnDraw( CDC * pDC )
{
 pDC->TextOut( 100, 100, "Hello View");
}

class CViewFrame : public CFrameWnd
{
public:
    CViewFrame( );

    virtual BOOL OnCmdMsg( UINT nID, int nCode, 
        void* pExtra, 
        AFX_CMDHANDLERINFO* pHandlerInfo );
       

    DECLARE_MESSAGE_MAP( )
public:
    afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct );

public:
    CMyView * m_pwndView;
//*请看这里,我们创建View的时候使用的是指针方式。没有采用     (类    对象;)方式。
老师说这里不能写成CMyView     m_pwndView;  (类    对象;)这种方式   因为在PostNcDestory()函数中有一个
delete   this;语句,所以为了防止内存释放掉两次  这里不能使用CMyView     m_pwndView;而必须使用  
CMyView * m_pwndView;   但是为什么在MFC使用向导创建出来的程序中就是用了 :
protected:  // control bar embedded members
CStatusBar     m_wndStatusBar;
CToolBar    m_wndToolBar;
CChildView    m_wndView;
我们可以看到:
CChildView    m_wndView;这种方式  为什么这种方式可以??????????????
*/

};

BEGIN_MESSAGE_MAP( CViewFrame, CFrameWnd )
    ON_WM_CREATE( )

END_MESSAGE_MAP( )

CViewFrame::CViewFrame( )
{
    m_pwndView = NULL;
}

int CViewFrame::OnCreate(LPCREATESTRUCT lpCreateStruct )
{
    CFrameWnd::OnCreate( lpCreateStruct );
    //View对象
    m_pwndView = new CMyView( );
    //创建View
    m_pwndView->Create( NULL, "View",
        WS_CHILD|WS_VISIBLE|WS_BORDER, 
        CRect( 100, 100, 200, 200 ),
        this, AFX_IDW_PANE_FIRST );

     SetActiveView( m_pwndView );

    //ModifyStyle( WS_BORDER )
    ModifyStyleEx( WS_EX_CLIENTEDGE, 0 );

    return 0;
}

BOOL CViewFrame::OnCmdMsg( UINT nID, int nCode, 
        void* pExtra, 
        AFX_CMDHANDLERINFO* pHandlerInfo )
{
      if( NULL != m_pwndView )
    {
        if( TRUE == m_pwndView->OnCmdMsg( nID,
            nCode, pExtra, pHandlerInfo ) )
        {
            return TRUE;
        }
    }

  
    return CFrameWnd::OnCmdMsg( nID, nCode,
        pExtra, pHandlerInfo );
}


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

CViewApp theApp;

BOOL CViewApp::InitInstance( )
{
    CViewFrame * pWnd = new CViewFrame( );
    pWnd->Create( NULL, "ViewApp",
        WS_OVERLAPPEDWINDOW,
         CFrameWnd::rectDefault, NULL,
        MAKEINTRESOURCE( IDR_MAINFRM ) );
    m_pMainWnd = pWnd;
    m_pMainWnd->ShowWindow( SW_SHOW );
    m_pMainWnd->UpdateWindow( );
    return TRUE;
}


[/quote] 销毁cmyview的代码在哪里[/quote] 前辈需要销毁代码???既然构造了,那么系统不是会自动的提供析构函数吗??所以不需要销毁代码,是这样吧!!!
信阳毛尖 2014-06-19
  • 打赏
  • 举报
回复
CView 在MFC文档视图框架下是通过RunTime动态创建的(不需要开发人员手动new)
yangxuefeng09 2014-06-19
  • 打赏
  • 举报
回复
引用 2 楼 lis2012 的回复:
你在析构函数里面是怎么处理,跟踪一下堆栈看看是哪里句柄位释放的情况下还在操作
请看在3楼上面的58行的问题,谢谢 ?????
yangxuefeng09 2014-06-19
  • 打赏
  • 举报
回复
引用 1 楼 lsq19871207 的回复:
CView 在MFC文档视图框架下是通过RunTime动态创建的(不需要开发人员手动new)
请看在3楼上面的58行的问题,谢谢 ?????
yangxuefeng09 2014-06-19
  • 打赏
  • 举报
回复
引用 1 楼 lsq19871207 的回复:
CView 在MFC文档视图框架下是通过RunTime动态创建的(不需要开发人员手动new)
// MFCView.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

class CMyView : public CView
{
public:
    virtual void OnDraw( CDC* pDC );
 
    DECLARE_MESSAGE_MAP( )
public:
    afx_msg void OnPaint( );
    afx_msg void OnTest( );
};

BEGIN_MESSAGE_MAP( CMyView, CView )
    ON_WM_PAINT( )
 ON_COMMAND( ID_TEST, OnTest )
END_MESSAGE_MAP( )

void CMyView::OnTest( )
{
    AfxMessageBox( "OnTest" );
}


void CMyView::OnPaint( )
{
    PAINTSTRUCT ps = { 0 };
    HDC hDC = ::BeginPaint( m_hWnd, &ps );
    TextOut( hDC, 100, 100, "View", 4 );
    ::EndPaint( m_hWnd, &ps );
}

void CMyView::OnDraw( CDC * pDC )
{
 pDC->TextOut( 100, 100, "Hello View");
}

class CViewFrame : public CFrameWnd
{
public:
    CViewFrame( );

    virtual BOOL OnCmdMsg( UINT nID, int nCode, 
        void* pExtra, 
        AFX_CMDHANDLERINFO* pHandlerInfo );
       

    DECLARE_MESSAGE_MAP( )
public:
    afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct );

public:
    CMyView * m_pwndView;
//*请看这里,我们创建View的时候使用的是指针方式。没有采用     (类    对象;)方式。
老师说这里不能写成CMyView     m_pwndView;  (类    对象;)这种方式   因为在PostNcDestory()函数中有一个
delete   this;语句,所以为了防止内存释放掉两次  这里不能使用CMyView     m_pwndView;而必须使用  
CMyView * m_pwndView;   但是为什么在MFC使用向导创建出来的程序中就是用了 :
protected:  // control bar embedded members
CStatusBar     m_wndStatusBar;
CToolBar    m_wndToolBar;
CChildView    m_wndView;
我们可以看到:
CChildView    m_wndView;这种方式  为什么这种方式可以??????????????
*/

};

BEGIN_MESSAGE_MAP( CViewFrame, CFrameWnd )
    ON_WM_CREATE( )

END_MESSAGE_MAP( )

CViewFrame::CViewFrame( )
{
    m_pwndView = NULL;
}

int CViewFrame::OnCreate(LPCREATESTRUCT lpCreateStruct )
{
    CFrameWnd::OnCreate( lpCreateStruct );
    //View对象
    m_pwndView = new CMyView( );
    //创建View
    m_pwndView->Create( NULL, "View",
        WS_CHILD|WS_VISIBLE|WS_BORDER, 
        CRect( 100, 100, 200, 200 ),
        this, AFX_IDW_PANE_FIRST );

     SetActiveView( m_pwndView );

    //ModifyStyle( WS_BORDER )
    ModifyStyleEx( WS_EX_CLIENTEDGE, 0 );

    return 0;
}

BOOL CViewFrame::OnCmdMsg( UINT nID, int nCode, 
        void* pExtra, 
        AFX_CMDHANDLERINFO* pHandlerInfo )
{
      if( NULL != m_pwndView )
    {
        if( TRUE == m_pwndView->OnCmdMsg( nID,
            nCode, pExtra, pHandlerInfo ) )
        {
            return TRUE;
        }
    }

  
    return CFrameWnd::OnCmdMsg( nID, nCode,
        pExtra, pHandlerInfo );
}


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

CViewApp theApp;

BOOL CViewApp::InitInstance( )
{
    CViewFrame * pWnd = new CViewFrame( );
    pWnd->Create( NULL, "ViewApp",
        WS_OVERLAPPEDWINDOW,
         CFrameWnd::rectDefault, NULL,
        MAKEINTRESOURCE( IDR_MAINFRM ) );
    m_pMainWnd = pWnd;
    m_pMainWnd->ShowWindow( SW_SHOW );
    m_pMainWnd->UpdateWindow( );
    return TRUE;
}


lis2012 2014-06-19
  • 打赏
  • 举报
回复
你在析构函数里面是怎么处理,跟踪一下堆栈看看是哪里句柄位释放的情况下还在操作

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧