对MFC中CDocument::UpdateAllViews的理解

来源:互联网 发布:python anaconda 编辑:程序博客网 时间:2024/05/16 19:44

对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窗口之外的所有窗口。

原创粉丝点击