在應(yīng)用開發(fā)構(gòu)成中,我們經(jīng)常在程序中加入一些打印語(yǔ)句,來對(duì)程序的執(zhí)行流進(jìn)行跟蹤.在C或C++中可以利用下列語(yǔ)句來實(shí)現(xiàn):
(1)
printf("enter %s\n",(char *)funcName);
或
cout<<"enter "<< s_funcName << endl;
但這樣處理有點(diǎn)不足,就是該語(yǔ)句只輸出到標(biāo)準(zhǔn)輸出上,我有時(shí)希望這些輸出被定向到特定文件,輸出成日志.為此,我們可以把這些函數(shù)進(jìn)行包裝,把輸出流ostream(標(biāo)準(zhǔn)輸出或文件輸出)作為包裝函數(shù)的一個(gè)參數(shù):
(2)
printWrap(ostream out,format, args);
注:此處的args, format表示要輸出的參數(shù)和相應(yīng)的參數(shù)格式.
當(dāng)然我們還可以對(duì)它進(jìn)行進(jìn)一步的改進(jìn):在該函數(shù)中,加入預(yù)定以的符號(hào)常量__LINE__(當(dāng)前源代碼行的行號(hào),為整數(shù)常量),__FILE__(假定的源文件名,某個(gè)字符串).這樣我們可以知道程序運(yùn)行到了那個(gè)源文件,并且那一行.
現(xiàn)在(2)中的處理方式比(1)中處理方式已經(jīng)有明顯的改善了.
但這種方式還稍微有點(diǎn)不足.當(dāng)我們想要跟蹤一個(gè)函數(shù)的執(zhí)行,即知到執(zhí)行流進(jìn)入某函數(shù),何時(shí)離開某函數(shù)時(shí),這種處理方式有點(diǎn)不足.每個(gè)函數(shù)都有一個(gè)入口,但可能有多個(gè)出口,這樣就需要在每個(gè)入口和出口處加上printWrap(ostream out,args)語(yǔ)句,并且在C++中,當(dāng)執(zhí)行流遇到異常退出該函數(shù)時(shí),可能有些printWrap語(yǔ)句并沒有被執(zhí)行,從而沒有輸出記錄.
為此,我們可以對(duì)(2)進(jìn)行進(jìn)一步改進(jìn).我們可以設(shè)計(jì)一個(gè)類,在該類對(duì)象的構(gòu)造函數(shù),析構(gòu)函數(shù)中進(jìn)行輸出.在函數(shù)的入口處,調(diào)用對(duì)象的構(gòu)造函數(shù)進(jìn)行輸出;在函數(shù)的出口處,或異常退出時(shí),調(diào)用對(duì)象的析構(gòu)函數(shù)進(jìn)行輸出.
我們可以把該類簡(jiǎn)單總結(jié)如下:
(3)
class Trace{
public:
Trace(int iDebugLevel,ostream out, format,args) { cout <<"Hello\n";}
~Trace() { cout << " Goodby\n";}
int getDebugLevel();
private:
...
int iDebugLevel;
ostream m_out;
};
注: 我們可以用printWrap(..)替換cout << ....。printWrap中的輸出流在Trace的構(gòu)造函數(shù)中傳到Trace實(shí)例中,并被保存。
我們還可以對(duì)它進(jìn)行一點(diǎn)改進(jìn),以提高它的性能。因?yàn)椴捎蒙厦娴膶?duì)象。則每次都會(huì)進(jìn)行輸出或進(jìn)行日志記錄.我們可以通過構(gòu)造函數(shù)在Trace的實(shí)例中,設(shè)置一個(gè)iDebugLevel變量和ostream。并在系統(tǒng)中設(shè)置一個(gè)統(tǒng)一的debugLevel.在每次進(jìn)行輸出時(shí)進(jìn)行iDebugLevel, debugLevel比較,如果iDebugLevel <= debugLevel, 則進(jìn)行輸出,否則則不進(jìn)行輸出.