MFC中的AssertValid和Dump函数

MFC中的AssertValid和Dump函数本文转载自:VC调试中,AssertValid和Dump函数的应用——————————————————————————AssertValid()函数——————————————————————–

大家好,又见面了,我是你们的朋友全栈君。

本文转载自:VC调试中,AssertValid和Dump函数的应用


—————————————–AssertValid()函数————————————-

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 函数的用户应注意该函数的限制。触发的断言指示对象一定有误,并且执行将暂停。但是,缺少断言只指示未找到任何问题,并不保证对象是好的。 

——————————————–Dump()函数—————————————-
当从 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/159054.html原文链接:https://javaforall.net

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


相关推荐

  • jquery正则表达式验证邮箱_正则表达式如何判断邮箱

    jquery正则表达式验证邮箱_正则表达式如何判断邮箱我的代码一开始如下:然后我的表单就一直没法成功调用这个函数,后面我发现,这里的跟java的不一样,reg里的正则表达式必须得用’/’,双引号赋值它不识别,还有下面调用test函数,上面if语句里面验证邮箱是否正确,用的email.test(reg),它打开网页还是没有提示。得像下面这个才能正常调用test。…

    2022年9月20日
    0
  • Matlab更改计算机用户名[通俗易懂]

    Matlab更改计算机用户名[通俗易懂]Matlab更改计算机用户名Matlab在安装的时候需要填写本地计算机的用户名,会和它的激活Licence绑定,我使用的是校园版。如果安装好之后更改了自己的计算机用户名,通常是Administrator;就会导致Matlab打开报错,可以通过重新进行激活的方式来更改之前的用户名1、找到Matlab的安装路径;然后bin目录;然后winXX(XX代表计算机位数);然后找到下面的active_matlab执行这个程序,后面就按照提示就可以了(比如我的路径:E:\MATLAB\bin\win64\

    2022年10月14日
    0
  • 超硬核!数据结构学霸笔记,考试面试吹牛就靠它

    超硬核!数据结构学霸笔记,考试面试吹牛就靠它上次发操作系统笔记,很快浏览上万,这次数据结构比上次硬核的多哦,同样的会发超硬核代码,关注吧。

    2022年6月21日
    33
  • SM4加密运算_数据加密标准des采用的密码类型是

    SM4加密运算_数据加密标准des采用的密码类型是javaSM4加密运算自己的理解:sm4加密,其实就是将字符串转成byte数组,再设置一个与解密相同的字符串,将byte的数据再转成二级制的数据,进行异或的运算,得到一组没有规则的字符串!案例上面是一些算法下面是应用方法这是自己的认知,有什么不同建议可以留言,XXXX是自己加密的字符串…

    2022年10月6日
    0
  • html模板代码_html模板代码下载

    html模板代码_html模板代码下载<!DOCTYPEhtml><htmllang=”en”><head><metacharset=”UTF-8″><metaname=”viewport”content=”width=device-width,initial-scale=1.0″><metahttp-equiv=”X-UA-Compatible”content=”ie=edge”><title>Doc

    2022年9月6日
    3

发表回复

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

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