AssertValid函数学�

AssertValid函数学�

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

转自http://tsitao.blog.163.com/blog/static/29795822006914105840496/

 

VC的调试中,AssertValid和Dump函数的应用

CObject::AssertValid 成员函数提供对对象内部状态的运行时检查。虽然从 CObject 派生类时不须要重写 AssertValid,但能够通过重写使您的类更安全可靠。AssertValid 应在对象的全部成员变量上运行断言,以验证它们包括有效值。比如,它应检查指针成员变量不为 NULL。

以下的演示样例显示怎样声明 AssertValid 函数:

class CPerson : public CObject

{

protected:

CString m_strName;

float m_salary;

public:

#ifdef _DEBUG

virtual void AssertValid() const; // Override

#endif

// …

};

当重写 AssertValid 时,在运行您自己的检查之前请调用 AssertValid 的基类版本号。然后使用 ASSERT 宏检查您的派生类特有的成员,例如以下所看到的:

#ifdef _DEBUG

void CPerson::AssertValid() const

{

// call inherited AssertValid first

CObject::AssertValid();

// check CPerson members…

ASSERT( !m_strName.IsEmpty()); // Must have a name

ASSERT( m_salary > 0 ); // Must have an income

}

#endif

假设不论什么成员变量存储对象,则能够使用 ASSERT_VALID 宏測试它们的内部有效性(假设它们的类重写了 AssertValid)。

比如,考虑 CMyData 类,该类在其成员变量之中的一个中存储了一个 CObList。CObList 变量 m_DataList 存储了一个 CPerson 对象的集合。CMyData 的简化声明例如以下所看到的:

class CMyData : public CObject

{

// Constructor and other members …

protected:

CObList* m_pDataList;

// Other declarations …

public:

#ifdef _DEBUG

virtual void AssertValid( ) const; // Override

#endif

// Etc. …

};

CMyData 中重写的 AssertValid 例如以下所看到的:

#ifdef _DEBUG

void CMyData::AssertValid( ) const

{

// Call inherited AssertValid

CObject::AssertValid( );

// Check validity of CMyData members

ASSERT_VALID( m_pDataList );

// …

}

#endif

CMyData 使用 AssertValid 机制測试其数据成员中存储的对象的有效性。CMyData 中重写的 AssertValid 为它自己的 m_pDataList 成员变量调用 ASSERT_VALID 宏。

由于 CObList 类也重写 AssertValid,所以有效性測试不在该级别停止。该重写对列表的内部状态运行附加有效性測试。因此,对 CMyData 对象的有效性測试将导致对存储的 CObList 列表对象内部状态的附加有效性測试。

再多进行一些操作,还能够加入�对存储在列表中的 CPerson 对象的有效性測试。能够从 CObList 派生 CPersonList 类,并重写 AssertValid。在重写中可调用 CObject::AssertValid,然后循环訪问列表,在列表中存储的每一个 CPerson 对象上调用 AssertValid。本主题開始所看到的的 CPerson 类已重写了 AssertValid。

当为调试生成时,这是一种功能极强的机制。当接着为公布生成时,该机制自己主动关闭。

AssertValid 的限制

给定类的 AssertValid 函数的用户应注意该函数的限制。触发的断言指示对象一定有误,而且运行将暂停。可是,缺少断言仅仅指示未找到不论什么问题,并不保证对象是好的。

当从 CObject 派生类时,在使用 DumpAllObjectsSince 将对象转储到“输出”窗体时,能够重写 Dump 成员函数以提供附加信息。

Dump 函数将对象的成员变量的文本化表示形式写入转储上下文 (CDumpContext)。转储上下文相似于 I/O 流。能够使用插入运算符 (<<) 向 CDumpContext 发送数据。

重写 Dump 函数时,应先调用 Dump 的基类版本号以转储基类对象的内容。然后为派生类的每一个成员变量输出文本化说明和值。

Dump 函数的声明例如以下所看到的:

class CPerson : public CObject

{

public:

#ifdef _DEBUG

virtual void Dump( CDumpContext& dc ) const;

#endif

CString m_firstName;

CString m_lastName;

// And so on…

};

由于对象转储仅仅在调试程序时有意义,所以 Dump 函数的声明用 #ifdef _DEBUG / #endif 块括起来。

在以下的演示样例中,Dump 函数先为其基类调用 Dump 函数。然后,它将每一个成员变量的简短说明与该成员的值一起写入诊断流。

#ifdef _DEBUG

void CPerson::Dump( CDumpContext& dc ) const

{

// Call the base class function first.

CObject::Dump( dc );

// Now do the stuff for our specific class.

dc << “last name: ” << m_lastName << “/n”

<< “first name: ” << m_firstName << “/n”;

}

#endif

必须提供 CDumpContext 參数以指定转储输出的目的地。MFC 的“Debug”版本号提供名为 afxDump 的提前定义 CDumpContext 对象,它将输出发送到调试器。

CPerson* pMyPerson = new CPerson;

// Set some fields of the CPerson object.

//…

// Now dump the contents.

#ifdef _DEBUG

pMyPerson->Dump( afxDump );

#endif

在 MFC 程序中,能够使用 DumpAllObjectsSince 转储有关堆中尚未释放的全部对象的说明。DumpAllObjectsSince 转储自上个 CMemoryState::Checkpoint 以来分配的全部对象。假设未发生 Checkpoint 调用,则 DumpAllObjectsSince 将转储当前在内存中的全部对象和非对象。

注意 必须先启用诊断跟踪,然后才干使用 MFC 对象转储。

注意 程序退出时 MFC 将自己主动转储全部泄漏的对象,因此不必创建代码在该点转储对象。

以下代码通过比較两个内存状态来測试内存泄漏,并在检測到泄漏时转储全部对象:

if( diffMemState.Difference( oldMemState, newMemState ) )

{

TRACE( “Memory leaked!/n” );

diffMemState.DumpAllObjectsSince();

}

转储的内容例如以下所看到的:

Dumping objects ->

{5} strcore.cpp(80) : non-object block at $00A7521A, 9 bytes long

{4} strcore.cpp(80) : non-object block at $00A751F8, 5 bytes long

{3} strcore.cpp(80) : non-object block at $00A751D6, 6 bytes long

{2} a CPerson at $51A4

Last Name: Smith

First Name: Alan

Phone #: 581-0215

{1} strcore.cpp(80) : non-object block at $00A7516E, 25 bytes long

大多数行開始处的大括号里的数字指定对象的分配顺序。近期分配的对象具有最高编号,并显示在转储的顶部。

AssertValid函数是用来推断表达式的合法性或正确性,假设不对或不合法则终止程序并返回对应的提示信息

如AssertValid(t==0);//用来推断t是否等于0,假设t!=0则终止程序

Dump函数一般用来显示debug信息的,其函数中的内容一般在debug时,在debug窗体中才干看到。

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Matlab绘制折线图详细方法

    Matlab绘制折线图详细方法Matlab绘制折线图属于非常基本的功能,首先给出一个示例代码,有详细的解释,可以根据自己需求进行修改。x=1:1:5;%x轴上的数据,第一个值代表数据开始,第二个值代表间隔,第三个值代表终止a=[203.024,113.857,256.259,244.888,293.376];%a数据y值b=[334.4,143.2,297.4,487.2,596.2];%b数据y值pl…

    2022年4月27日
    55
  • pycharm2018打不开_pycharm indexing

    pycharm2018打不开_pycharm indexingpycharm2020无法打开,点击无反应,今天我碰到这现象,总结大体原因为2种第1种:C:\Users\ygw\AppData\Roaming\JetBrains(删除该目录即可,一般由于升级安装或安装两个不同版本会存在老旧文件影响导致)第2种:进行过激活成功教程,修改了pycharm64.exe.vmoptions配置,其中存在错误配置或配置中的指定jar…

    2022年8月29日
    1
  • html中ul和li的使用_ul列表的html结构

    html中ul和li的使用_ul列表的html结构html中偶尔会使用到列表,记录一下。1.序号可以是数字、字母、罗马数字等,可以通过list-style-type属性设置。2.序号也可以显示图片,可以通过list-style-image

    2022年8月1日
    10
  • postman进行http接口测试

    postman进行http接口测试无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。HTTP的接口测试工具有很多,可以进行http请求的方式也有很多,但是可以直接拿来就用,而且功能还支持的不错的,我使用过的来讲,还是postman比较上手。优点:1、支持用例管理2、支持get、post、文件上…

    2022年5月10日
    39
  • bootstrap使用教程_bootstrap 教程

    bootstrap使用教程_bootstrap 教程bootStrap是干嘛的?有什么用处?我们在开发前端页面的时候,如果每一个按钮、样式、处理浏览器兼容性的代码都要自己从零开始去写,那就太浪费时间了。所以我们需要一个框架,帮我们实现一个页面的基础部分和解决一些繁琐的细节,只要在它的基础上进行个性化定制就可以了。Bootstrap就是这样一个简洁、直观、强悍的前端开发框架,只要学习并遵守它的标准,即使是没有学过网页设计的开发者,也能做出很…

    2022年10月9日
    3
  • goland-2022.01激活码_在线激活2022.02.22「建议收藏」

    (goland-2022.01激活码)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlHCIQ56F36O-eyJsa…

    2022年4月1日
    67

发表回复

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

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