和printf函数一样,输出调试信息,信息输出在DEBUG输出栏中,DEBUG有效,RELEASE下无效。
TRACE("TRACE:this is trace %s", "test");
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>
同ASSERT宏,只是在Release下仍有效。
用来检查一个对象的内部合法性,比如说现在有一个学生对象,我们知道每个学生的年龄一定大于零,若年龄小于零,则该学生对象肯定有问题。注意:不是所有对象都可以用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();
.