★多文档中,pDocTemplate什么时候被delete的?如果是自己new 的CMultiDocTemplate,要不要删除,在哪里删除?

52001314 2003-03-27 05:12:58
在App中InitInstance()里,

CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(
IDR_SMSTYPE,
RUNTIME_CLASS(CMYDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CMYView));
AddDocTemplate(pDocTemplate);

这个pDocTemplate系统是在哪里delete的?

如果自己加了一个template,要在哪里delete?
pMyDocTemplate = new CMultiDocTemplate(
IDR_SMSTYPE,
RUNTIME_CLASS(CMYDoc1),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CMYView1));

如果自己的函数中打开文档
m_pDoc = pTemplate->OpenDocumentFile(NULL);
要不要做delete工作?是不是pTemplate删除了,doc就自动删除了?
...全文
304 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
lzhyu 2003-08-26
  • 打赏
  • 举报
回复
Thank you all!
52001314 2003-04-04
  • 打赏
  • 举报
回复
非常感谢webber84(***闭关修炼中***) 和In355Hz(好象一条狗)

结贴了。如果有人有不同意见,请继续发表。
In355Hz 2003-04-02
  • 打赏
  • 举报
回复
我也同意 webber84(***闭关修炼中***) 的看法,记得那天我也注意了 bStaticInit ,但是没有看到何时 bStaticInit = FALSE
webber84 2003-04-02
  • 打赏
  • 举报
回复
应该是NULL。
52001314 2003-04-02
  • 打赏
  • 举报
回复
谢谢 webber84(***闭关修炼中***)

我觉得你是正确的。不过如果这样的话,我们平时的SDI,MDI中,CDocManager::pStaticList应该都是NULL了?

不知道其他大侠还有什么见解吗?
webber84 2003-03-31
  • 打赏
  • 举报
回复
to 52001314(生命在于运动):

那天回贴太仓促,的确犯了你说的错误。今天仔细看了一下MFC的源码,得出的结果还是必须自己deleteCDocManager类有这么几个静态成员:
class CDocManager : public CObject
{
public:
static CPtrList* pStaticList; // for static CDocTemplate objects
static BOOL bStaticInit; // TRUE during static initialization
static CDocManager* pStaticDocManager; // for static CDocTemplate objects
}
相信你也看到MFC开发人员的注释,这些都是给静态的CDoctemplate对象准备的。这三个成员分别被初始化为TRUE,NULL,NULL。然后你看CWinApp的InitApplication函数:
BOOL CWinApp::InitApplication()
{
if (CDocManager::pStaticDocManager != NULL)
{
if (m_pDocManager == NULL)
m_pDocManager = CDocManager::pStaticDocManager;
CDocManager::pStaticDocManager = NULL;
}

if (m_pDocManager != NULL)
m_pDocManager->AddDocTemplate(NULL);
else
CDocManager::bStaticInit = FALSE;
return TRUE;
}
如果CDocManager::pStaticDocManager!=NULL,那么 m_pDocManager被指向pStaticDocManager。但是pStaticDocManager是被初始化为NULL的,只有一个地方可以改变它的值,就是在CDocTemplate的构造函数中:
CDocTemplate::CDocTemplate()
{
………………
if (CDocManager::bStaticInit)
{
if (CDocManager::pStaticList == NULL)
CDocManager::pStaticList = new CPtrList;
if (CDocManager::pStaticDocManager == NULL)
CDocManager::pStaticDocManager = new CDocManager;
CDocManager::pStaticList->AddTail(this);
}
}
注意只有一种情况下CDocTemplate的构造函数会先InitApplication执行,那就是你定义了一个全局的CDocTemplate对象。除些以外,InitApplication执行时CDocManager::pStaticDocManager必定为NULL。而此时CWinApp::m_pDocManager也是为NULL的,于是CDocManager::bStaticInit就在InitApplication被设为了false. 从前面列出的CDocTemplate的构造函数可以看到,只有在CDocManager::bStaticInit为TRUE的情况下,对象才会被加到CDocManager::pStaticList中。

从上面的执行情况说明,如果你new了一个CDocTemplate对象而没有调用AddDocTemplate,就必须自己delete,否则就有内存泄漏。这一点我已经在MFC中验证过了。
UDX协议 2003-03-31
  • 打赏
  • 举报
回复
不需要自己删除!
自己删也没错啊~
elvahuang 2003-03-31
  • 打赏
  • 举报
回复
呵呵
好热哦

studying
52001314 2003-03-31
  • 打赏
  • 举报
回复
至于m_pDoc = pTemplate->OpenDocumentFile(NULL);
要不要做delete工作?
In355Hz(好象一条狗) ( ) 信誉:110 2003-03-27 17:43:00 得分:0


CDocTemplate::CloseAllDocument() 通过调用 CDocument::OnCloseDocument 清除所有打开的文档,从 OnCloseDocument 的代码中可以看见这个函数关闭了所有 ChildFrame / View , 并 delete this

这是正确的。下面是我查到的。
文档何时被析构?

在SDI程序中,程序退出后文档就被删除。在MDI程序中,与该文档相关的最后一个视图关闭时文档就被删除。

CView::~CView()
{
if (m_pDocument != NULL)
m_pDocument->RemoveView(this);
}

void CDocument::RemoveView(CView* pView)
{
ASSERT_VALID(pView);
ASSERT(pView->m_pDocument == this); // must be attached to us

m_viewList.RemoveAt(m_viewList.Find(pView));
pView->m_pDocument = NULL;

OnChangedViewList(); // must be the last thing done to the document
}

void CDocument::OnChangedViewList()
{
// if no more views on the document, delete ourself
// not called if directly closing the document or terminating the app
if (m_viewList.IsEmpty() && m_bAutoDelete)
{
OnCloseDocument();//这里就执行了In355Hz所说的函数了。
return;
}

// update the frame counts as needed
UpdateFrameCounts();
}

void CDocument::OnCloseDocument()
// must close all views now (no prompting) - usually destroys this
{
// destroy all frames viewing this document
// the last destroy may destroy us
BOOL bAutoDelete = m_bAutoDelete;
m_bAutoDelete = FALSE; // don't destroy document while closing views
while (!m_viewList.IsEmpty())
{
// get frame attached to the view
CView* pView = (CView*)m_viewList.GetHead();
ASSERT_VALID(pView);
CFrameWnd* pFrame = pView->GetParentFrame();
ASSERT_VALID(pFrame);

// and close it
PreCloseFrame(pFrame);
pFrame->DestroyWindow();
// will destroy the view as well
}
m_bAutoDelete = bAutoDelete;

// clean up contents of document before destroying the document itself
DeleteContents();

// delete the document if necessary
if (m_bAutoDelete)
delete this;//这里就删除CDocument*指针了。
}
}
ukyoking 2003-03-31
  • 打赏
  • 举报
回复
真长见识了
52001314 2003-03-31
  • 打赏
  • 举报
回复
CDocTemplate::CDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass,
CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass)
{
....
/ add to pStaticList if constructed as static instead of on heap
if (CDocManager::bStaticInit)
{
m_bAutoDelete = FALSE;
if (CDocManager::pStaticList == NULL)
CDocManager::pStaticList = new CPtrList;
if (CDocManager::pStaticDocManager == NULL)
CDocManager::pStaticDocManager = new CDocManager;
CDocManager::pStaticList->AddTail(this);
}
else
{
m_bAutoDelete = TRUE; // usually allocated on the heap
LoadTemplate();
}
}

to webber84(***闭关修炼中***) :

CMultiDocTemplate是CDocTemplate的派生类,所以new一个CMultiDocTemplate,应该是先执行CDocTemplate的构造函数,再执行CMultiDocTemplate的构造函数。会自动的在 static 表 CDocManager::pStaticList 中添加自己。

以上是我的理解,不知道正确已否。请大家继续发表意见。
52001314 2003-03-31
  • 打赏
  • 举报
回复
前几天出差了。多谢这么多大侠来捧场。

看了一下楼上的,发现不管有没有AddDocTemplate(pDocTemplate);标准的CWinApp的析构函数都会删除这些对象。

CWinApp::~CWinApp()
{
// free doc manager
if (m_pDocManager != NULL)
delete m_pDocManager;

// free recent file list
if (m_pRecentFileList != NULL)
delete m_pRecentFileList;

// free static list of document templates
if (!afxContextIsDLL)
{
if (CDocManager::pStaticList != NULL)
{
delete CDocManager::pStaticList;
CDocManager::pStaticList = NULL;
}
if (CDocManager::pStaticDocManager != NULL)
{
delete CDocManager::pStaticDocManager;
CDocManager::pStaticDocManager = NULL;
}
}
......
}

class CDocManager : public CObject
{
.....
public:
static CPtrList* pStaticList; // for static CDocTemplate objects
static BOOL bStaticInit; // TRUE during static initialization
static CDocManager* pStaticDocManager; // for static CDocTemplate objects
...
}
webber84 2003-03-27
  • 打赏
  • 举报
回复
to In355Hz(好象一条狗):
你说的是CDocTemplate的构造函数。而楼主问的是CMultiDocTemplate。CMultiDocTemplate的构造函数是不会去创建CDocManager::pStaticList,再把自己加到里面去的。所以如果new一个CMultiDocTemplate而不调用AddDocTemplate,最后必须要delete,否则就会内存汇漏。在MFC中调试一下就可以证明这一点。
CCBeyond 2003-03-27
  • 打赏
  • 举报
回复
星星真多,明天肯定出太阳!
In355Hz 2003-03-27
  • 打赏
  • 举报
回复
我错了...更正,psusong(在黑夜中寂寞成长的橡树) 说的对,都不需要显式的 delete

CDocTemplate::CDocTemplate 会自动的在 static 表 CDocManager::pStaticList 中添加自己,如果 AddDocTemplate 被调用,CDocManager 会收集所有在 pStaticList 中的 DocTemplate,无论怎样,pStaticList 和 CDocManager 都会在 CWinApp::~CWinApp 中清除,并 delete 所有的 DocTemplate
hzwanglw 2003-03-27
  • 打赏
  • 举报
回复
都是星,学习ing
GoogleGeek 2003-03-27
  • 打赏
  • 举报
回复
不需要自己删除!
标准的CWinApp的析构函数负责删除这些对象
In355Hz 2003-03-27
  • 打赏
  • 举报
回复
CDocTemplate::CloseAllDocument() 通过调用 CDocument::OnCloseDocument 清除所有打开的文档,从 OnCloseDocument 的代码中可以看见这个函数关闭了所有 ChildFrame / View , 并 delete this
In355Hz 2003-03-27
  • 打赏
  • 举报
回复
如果是没有通过 AddDocTemplate 注册的 DocTemplate ,恐怕需要自己在 CWinApp::~CWinApp 中 CloseAllDocuments() 并 delete
webber84 2003-03-27
  • 打赏
  • 举报
回复
doctemplate是由CDocManager管理的,这是CDocManager的析构函数:
CDocManager::~CDocManager()
{
// for cleanup - delete all document templates
POSITION pos = m_templateList.GetHeadPosition();
while (pos != NULL)
{
POSITION posTemplate = pos;
CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetNext(pos);
if (pTemplate->m_bAutoDelete)
{
m_templateList.RemoveAt(posTemplate);
delete (CDocTemplate*)pTemplate;
}
}
}
从上面可以看出,只要你的doctemplate在创建的时候设置m_bAutoDelete为true,那么在CDocManger析构的时候会自动删除,否则要你自己delete。
以上只是在你调用了AddDocTemplate把template交给docmanager的情况下讨论的。如果你没有调用AddDocTemplate,那么模板要你自己删除。
加载更多回复(1)

16,471

社区成员

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

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

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