zoukankan      html  css  js  c++  java
  • ASSERT_VALID和ASSERT宏分析

    这个宏都是MFC的调试宏.

    ASSERT_VALID宏用来在运行时检查一个对象的内部合法性,比如说现在有一个学生对象,我们知道每个学生的年龄一定大于零,若年龄小于零,则该学生对象肯定有问题。

    事实上,ASSERT_VALID宏就是转化为对象的成员函数AssertValid()的调用,只是这种方法更安全。它的参数是一个对象指针,通过这个指针来调用它的AssertValid()成员函数。

    与此相配套,每当我们创建从Cobject类继承而来的一个新的类时,我们可以重载该成员函数,以执行特定的合法性检查


    ASSERT_VALID强制调用参数对象(必须是CObject或CObject*)的AssertValid函数,该函数实现对象的内部一致性检查,当你创建一个可重用类时,应该重载这个函数(VC中缺省已经重载了该函数),你可以在该函数中进行必要的检查工作.
    ASSERT宏用于确保参数内的表达式正确,如果表达式为false,则会显示一个消息对话框,其中有源文件的名字和当前行号,用户可以选择中断程序或进行调试.这个宏通常用于校验参数和返回值.
    以上两个宏均只在Debug版本中有效,与ASSERT相对应的是VERIFY.VERIFY宏在Debug版本中与ASSERT相同,在Release版本中仅执行参数表达式,不进行校验.

    ASSERT 和 ASSERT_VALID
    都是用于Debug的,当括号中的表达式为FALSE时,会弹出对话框通知,
    你可以自己加上一句ASSERT(FALSE),看看执行时有什么东东。

    ASSERT_VALID用于对C++对象或指针进行有效性判断,如果出错,结果和ASSERT一样。

    注意:二者都只能在MFC工程里用。
    以下是ASSERT_VALID对应的代码:


    #ifdef _DEBUG
    void AFXAPI AfxAssertValidObject(const CObject* pOb,
    LPCSTR lpszFileName, int nLine)
    {
    if (pOb == NULL)
    {
       TRACE(traceAppMsg, 0, "ASSERT_VALID fails with NULL pointer.\n");
       if (AfxAssertFailedLine(lpszFileName, nLine))
        AfxDebugBreak();
       return;     // quick escape
    }
    if (!AfxIsValidAddress(pOb, sizeof(CObject)))
    {
       TRACE(traceAppMsg, 0, "ASSERT_VALID fails with illegal pointer.\n");
       if (AfxAssertFailedLine(lpszFileName, nLine))
        AfxDebugBreak();
       return;     // quick escape
    }

    // check to make sure the VTable pointer is valid
    ASSERT(sizeof(CObject) == sizeof(void*));
    if (!AfxIsValidAddress(*(void**)pOb, sizeof(void*), FALSE))
    {
       TRACE(traceAppMsg, 0, "ASSERT_VALID fails with illegal vtable pointer.\n");
       if (AfxAssertFailedLine(lpszFileName, nLine))
        AfxDebugBreak();
       return;     // quick escape
    }

    if (!AfxIsValidAddress(pOb, pOb->GetRuntimeClass()->m_nObjectSize, FALSE))
    {
       TRACE(traceAppMsg, 0, "ASSERT_VALID fails with illegal pointer.\n");
       if (AfxAssertFailedLine(lpszFileName, nLine))
        AfxDebugBreak();
       return;     // quick escape
    }
    pOb->AssertValid();
    }

    在Win32环境下通过测试

    #include <afx.h>

    class CPerson : public CObject
    {
    public:

           CPerson(char *pName, int nAge);

    #ifdef _DEBUG

           virtual void AssertValid() const;

    #endif

    private:

           char *m_strname;

           int m_nage;
    };

    CPerson::CPerson(char *pName, int nAge) : m_strname(pName), m_nage(nAge)
    {

    }

    #ifdef _DEBUG

    void CPerson::AssertValid() const
    {

           CObject::AssertValid();

           ASSERT(m_strname);

           ASSERT(m_nage>0);
    }

    #endif

    int main()
    {

           //CString strName("listen");

           //CPerson *pPersonOne = new CPerson(strName.GetBuffer(0), -5);

          
     CString strName("listen");
     char *pcstr = (char *)new char[2 * strName.GetLength()+1] ;

     WideCharToMultiByte(   CP_ACP,  
      0,  
      strName,     //   要转换的wchar_t*  
      -1,  
      pcstr,   //   接收char*的缓冲区指针  
      2 * strName.GetLength()+1,         //   pcstr的缓冲区的大小  
      NULL,  
      NULL   );
     CPerson *pPersonOne = new CPerson(pcstr, 5);

    #ifdef _DEBUG

           pPersonOne->AssertValid();

    #endif

           return 0;
    }

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/chocolateconanlan/archive/2009/04/08/4057452.aspx

  • 相关阅读:
    系统进程查看 --- 微软官方出品
    Chrome 浏览器网页保存为PDF文件
    Chrome Google浏览器下载
    最强Android书 架构大剖析 作者网站
    腾讯暑期夏令营之旅
    轨迹记录App是怎样对定位轨迹进行过滤、优化和平滑处理的
    android-8~23 View.java
    android-23 View.java
    The server encountered an internal error that prevented it from fulfilling this request.
    Android Event
  • 原文地址:https://www.cnblogs.com/joeblackzqq/p/1906742.html
Copyright © 2011-2022 走看看