高级调试技术

TRACE宏

和printf函数一样,输出调试信息,信息输出在DEBUG输出栏中,DEBUG有效,RELEASE下无效。

 

TRACE("TRACE:this is trace %s", "test");

ASSERT宏

assert宏的原型定义在<assert.h>,宏的参数为逻辑表达式,表达式为真则不会发生任何动作,表达式为假,系统弹出警告框,并停止程序运行,同时要求做出选择Abort、Ignore、Retry。DEBUG下有效,RELEASE下无效。

实例:

	fp = fopen( "123.txt", "r" );			//以只读的方式打开一个文件,如果不存在就打开文件失败
	assert( fp );                           //所以这里出错
	fclose( fp );                           //程序永远都执行不到这里来

缺点:频繁的调用会极大的影响程序的性能,增加额外的开销。不过可以通过包含#include <assert.h>的语句之前插入 #define NDEBUG 来禁用assert调用,示例代码如下:

#define NDEBUG
#include <assert.h>

VERIFY宏

同ASSERT宏,只是在Release下仍有效。

 

ASSERT_VALID宏

用来检查一个对象的内部合法性,比如说现在有一个学生对象,我们知道每个学生的年龄一定大于零,若年龄小于零,则该学生对象肯定有问题。注意:不是所有对象都可以用ASSERT_VALID宏,需要派生自CObject。

事实上,ASSERT_VALID宏就是转化为对象的成员函数AssertValid()的调用,只是这种方法更安全。它的参数是一个对象指针,通过这个指针来调用它的AssertValid()成员函数。与此相配套,每当我们创建从Cobject类继承而来的一个新的类时,我们可以重载该成员函数,以执行特定的合法性检查。

ASSERT_VALID强制调用参数对象(必须是CObject或CObject*)的AssertValid函数,该函数实现对象的内部一致性检查,当你创建一个可重用类时,应该重载这个函数(VC中缺省已经重载了该函数),你可以在该函数中进行必要的检查工作.
ASSERT_VALID也用于对C++对象或指针进行有效性判断,如果出错,结果和ASSERT一样。

实例:

头文件Person.h

#pragma once
#include "afx.h"

class CPerson :
	public CObject
{
protected: 
	CString m_strName; 
	float m_salary; 

public:
	CPerson(void);
	CPerson(CString strName, float fSalary);
	~CPerson(void);

public:
#ifdef _DEBUG 
	virtual void AssertValid() const; // Override 
#endif 

};

资源文件

#include "StdAfx.h"
#include "Person.h"

CPerson::CPerson(CString strName, float fSalary):m_strName(strName), m_salary(fSalary)
{
}

CPerson::CPerson(void)
{
}

CPerson::~CPerson(void)
{
}

#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 

使用:

	//CPerson person(_T("王二"), 23);
	CPerson person;
	ASSERT_VALID(&person);				//此处等同于调用person.AssertValid();




 

.

你可能感兴趣的:(高级调试技术)