您的位置:首页 > 其它

对MFC中CDocument::UpdateAllViews的理解

2017-06-22 16:18 288 查看
对MFC中CDocument::UpdateAllViews的理解:

void CDocument::UpdateAllViews(CView* pSender, LPARAM lHint, CObject* pHint)

 // walk through all views

{

 ASSERT(pSender == NULL || !m_viewList.IsEmpty());

 POSITION pos = GetFirstViewPosition();

 while (pos != NULL)

 {

  CView* pView = GetNextView(pos);

  ASSERT_VALID(pView);

  if (pView != pSender)

   pView->OnUpdate(pSender, lHint, pHint);

 }

}

对其中ASSERT(pSender == NULL || !m_viewList.IsEmpty());的理解:

根据我的跟踪,我发现MFC是这样设计的这个函数

函数调用原理:

如果pSender为NULL,说明该函数始终文档类的成员函数中被调用,

此时就要更新与该文档类相关联的所有View类。

如果pSender不为NULL,说明该函数是在某一个View类的成员函数中被调用的。

代码解释:

ASSERT宏的原型为:ASSERT(f)

当pSender为NULL时,||的左边为TRUE,所有整个||(即pSender == NULL || !m_viewList.IsEmpty())

为TRUE,此时ASSERT不会执行!m_viewList.IsEmpty()。这个时候,MFC会让与该文档类相关联的所有

View类得到更新(MFC不会在ASSERT这一步去判断与该文档类相关联的View类的个数是否为0)。此时

直接去执行下面的语句。

当pSender不为NULL时,pSender == NULL为假,此时还不能判断“pSender == NULL || !m_viewList.IsEmpty()”

的真假,因此ASSERT还需要去执行!m_viewList.IsEmpty()。在MFC中IsEmpty()的设计为:

_AFXCOLL_INLINE BOOL CPtrList::IsEmpty() const

 { return m_nCount == 0; }

可以看到,m_viewList.IsEmpty()始终为FALSE,因此!m_viewList.IsEmpty()始终为TRUE。在这里MFC做了一个

绝对成立的假设,即:如果UpdateAllViews是在某一个View类的成员函数中被调用(此时pSender不为NULL时),

那么,此时至少有一个View类与此文档类相关联,因此,程序没有出现错误,代码可以继续运行,去更新与此

文档类相关联的除该View窗口之外的所有窗口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: