關於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類在內存中的地址。