关于TRACE宏
1:具体内容具体内容见《VC技术内幕》(第四版)第296页,或者在MSDN上搜TN007.
在TRACE.EXE中可以对TRACE功能进行配置。
关于afxDump对象:
class CDumpContext
{
public:
CDumpContext(CFile* pFile = NULL);
// Attributes
int GetDepth() const; // 0 => this object, 1 => children objects
void SetDepth(int nNewDepth);
// Operations
CDumpContext& operator<<(LPCTSTR lpsz);
#ifdef _UNICODE
CDumpContext& operator<<(LPCSTR lpsz); // automatically widened
#else
CDumpContext& operator<<(LPCWSTR lpsz); // automatically thinned
#endif
CDumpContext& operator<<(const void* lp);
CDumpContext& operator<<(const CObject* pOb);
CDumpContext& operator<<(const CObject& ob);
CDumpContext& operator<<(BYTE by);
CDumpContext& operator<<(WORD w);
CDumpContext& operator<<(UINT u);
CDumpContext& operator<<(LONG l);
CDumpContext& operator<<(DWORD dw);
CDumpContext& operator<<(float f);
CDumpContext& operator<<(double d);
CDumpContext& operator<<(int n);
void HexDump(LPCTSTR lpszLine, BYTE* pby, int nBytes, int nWidth);
void Flush();
// Implementation
protected:
// dump context objects cannot be copied or assigned
CDumpContext(const CDumpContext& dcSrc);
void operator=(const CDumpContext& dcSrc);
void OutputString(LPCTSTR lpsz);
int m_nDepth;
public:
CFile* m_pFile;
};
afxDump用法和C++中的cout很像。
afxDump和TRACE宏都是在Output窗口中进行输出。
注意:
1:afxDump只可以在Debug模式下使用,在Debug目标中使用不能通过编译。因此,使用afxDump对象时应该加上_DEBUG宏开关,
这样便可以保证写出的程序从Debug目标变成Release目标时不需要对代码进行修改即可正常运行^_^
3:在Release目标中,诊断信息存储被禁用,诊断代码不会被连进程序中。
CDumpContext类的实现在DUMPCONT.CPP文件中
all CDumpContext output is controlled by afxTraceEnabled
CDumpContext& CDumpContext::operator<<(const CObject& ob)
{
return *this << &ob;
}
CDumpContext& CDumpContext::operator<<(const CObject* pOb)
{
#ifdef _DEBUG // all CDumpContext output is controlled by afxTraceEnabled
if (!afxTraceEnabled)
return *this;
#endif //_DEBUG
if (pOb == NULL)
*this << _T("NULL");
else
#ifdef _AFXDLL
pOb->Dump(*this);
#else
*this << _T("Unable to dump object in static release builds");
#endif
return *this;
}
由上面代码可以看出,当我想在一个CObject派生类中使用CDumpContext类的对象时,实际上是调用了CObject类中的虚函数Dump.
由 pOb->Dump(*this);可以看出,本质上是CObject派生类(如CAction类)调用了CAction重写过的Dump函数(如果Dump函数在CAction类中被重写了的话),并以一个指向它自己的指针作为参数。在重写的Dump函数中,我们就可以按照我们的想法在Output窗口输出CAction类的信息。
在CObject类中,Dump函数的实现如下:
void CObject::Dump(CDumpContext& dc) const
{
dc << "a " << GetRuntimeClass()->m_lpszClassName <<
" at " << (void*)this << "/n";
UNUSED(dc); // unused in release build
}
这里是得到了CAction类在内存中的地址。