ASSERT 和 ASSERT_VALID[通俗易懂]

ASSERT 和 ASSERT_VALID[通俗易懂]这个宏都是MFC的调试宏.ASSERT_VALID宏用来在运行时检查一个对象的内部合法性,比如说现在有一个学生对象,我们知道每个学生的年龄一定大于零,若年龄小于零,则该学生对象肯定有问题。事实上,ASSERT_VALID宏就是转化为对象的成员函数AssertValid()的调用,只是这种方法更安全。它的参数是一个对象指针,通过这个指针来调用它的AssertValid()成员…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

这个宏都是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;
}

 

转载于:https://www.cnblogs.com/fengbing/articles/2794219.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196728.html原文链接:https://javaforall.net

(0)
上一篇 2025年9月21日 上午11:15
下一篇 2025年9月21日 上午11:43


相关推荐

  • 二叉树的先序、中序、后序遍历序列

    二叉树的先序、中序、后序遍历序列nbsp nbsp nbsp nbsp 二叉树的遍历主要有三种 1 先 根 序遍历 根左右 2 中 根 序遍历 左根右 3 后 根 序遍历 左右根 举个例子 先 根 序遍历 根左右 ABDHEICFJKG 中 根 序遍历 左根右 DHBEIAJFKCG 后 根 序遍历 左右根 HDIEBJKFGCA nbsp nbsp nbsp nbsp 以后 根 序

    2026年3月26日
    2
  • MySQL中的注释符号的使用

    MySQL中的注释符号的使用原文地址 http paulfzm iteye com blog 前言在学习 MySQL 的过程中 因为目前接触的语法简单 所以实在没有想到过加入注释 在写博客使用 Markdown 时 突然想用注释语句 所以便百度了一下 引用了这一篇转载博客 MySQL 中的注释符号有三种 注意事项 其中 表示注释的文本内容 在使用 注释

    2025年9月5日
    7
  • leetcode-53最大子序和(离线|分治)「建议收藏」

    leetcode-53最大子序和(离线|分治)「建议收藏」给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。示例 1:输入:nums = [-2,1,-3,4,-1,2,1,-5,4]输出:6解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。示例 2:输入:nums = [1]输出:1示例 3:输入:nums = [0]输出:0示例 4:输入:nums = [-1]输出:-1示例 5:输入:nums = [-100000]输出:-100000 提示:1

    2022年8月8日
    8
  • 最基础_负数二进制转换

    最基础_负数二进制转换负数的二进制对于一个十进制数值先转化为二进制数值 不够八位则在前补零凑够 即为原码取反 0 变 1 1 变 0 即为反码反码 1 变为补码 这里的补码是负数在计算机中的二进制表示方法 如果要表示 16 位的二进制数值 此时在数值左侧补 1 即可 原码补 0 反码补 1 如果是负数二进制转换十进制反之即可例如 13 按照如上方法会得出二进制数为而 13 二进制数值为

    2026年3月18日
    2
  • pycharm 滚轮字体大小设置_pycharm中文字体设置

    pycharm 滚轮字体大小设置_pycharm中文字体设置pycharm用鼠标滚轮控制字体大小一、file–>settings或者工具栏中点击二、搜索increase三、双击increaseFrontsize进入AddMouseShortcut四、摁住ctrl向上滚动鼠标滑轮。点击ok,即可实现ctrl+向上滚轮增加字体 大小。五、实现减小字体大小搜索decrease同上类似操作即可完成…

    2025年8月3日
    6
  • Mybatis源码分析_struts源码

    Mybatis源码分析_struts源码Mybatis提供了一个简单的逻辑分页类RowBounds,其原理类似于在内存中做了一个分页,不是数据库层面的分页,性能不算好,谨慎使用一.RowBounds源码分析1RowBounds源码:/***Copyright2009-2017theoriginalauthororauthors.**LicensedundertheApacheLicense,Version2.0(the”License”);*youmaynot.

    2026年2月13日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号