2009-08-25 30 views
0

我試圖寫一個簡單的審計類,通過操作< <需要輸入和接收定製的機械手這樣以後寫審計:定製的流處理器爲

class CAudit 
{ 
public: 
    //needs to be templated 
    CAudit& operator << (LPCSTR data) { 
     audittext << data; 
     return *this; 
    } 

    //attempted manipulator 
    static CAudit& write(CAudit& audit) { 
     //write contents of audittext to audit and clear it 
     return audit; 
    } 

private: 
    std::stringstream audittext; 
}; 

//to be used like 
CAudit audit; 
audit << "Data " << data << " received at " << time << CAudit::write; 

我認識到,重載運營商我的代碼沒有返回流對象,但想知道是否仍然可以使用像句法這樣的操縱符。目前,編譯器將'< <'視爲二進制右移運算符。

感謝您的任何輸入, 帕特里克

回答

4

爲了使它工作,你必須爲功能添加其中的超負荷運營商< <的, 比調用函數:

class CAudit 
{ 
    //...other details here as in original question 

    CAudit& operator << (CAudit & (*func)(CAudit &)) 
    { 
     return func(*this); 
    } 
}; 

CAudit audit; 
audit << "some text" << CAudit::write; 
+0

謝謝,最後打造 – Patrick 2009-08-25 14:51:10

1

這是不是

class CAudit 
{ 
public: 
    template< typename T > 
    CAudit& operator<<(const T& data) 
    { 
     audittext << data; 
     return *this; 
    } 

    class write {}; 

    void operator<<(const write& data) 
    { 
     /* whatever */ 
    } 

private: 
    std::stringstream audittext; 
}; 

你想要做什麼?

+0

感謝您的答案,看起來它會以類似羅布森的答案的方式工作,可能會嘗試使用函數來擺脫函數指針參數。 – Patrick 2009-08-25 14:53:47

2

二進制移位運算符和流運算符是同一個運營商。將operator +重載到std :: cout上寫下「Hello world」是完全合法的(儘管這是一個非常糟糕的主意)。與C++標準作者一樣,決定將數據流的運算符< <超載爲寫入流。
你沒寫清楚你的問題。我的猜測是編譯錯誤。在這種情況下最好的是引用錯誤信息。如果我是對的,問題是,您只爲LPCSTR定義了運算符< <,然後您希望它在右側工作函數對象。
您使用單詞「操縱器」,但你誤解了某些東西。流的操縱器(來自STL的流)是一個函數,用於對寫入的流執行一些操作。它只適用於這種過載:

ostream& operator<< (ostream& (*pf)(ostream&)); 

它接受函數並將其應用於流。
同樣需要:

CAudit& operator<< (CAudit& (*pf)(CAudit& audit)) 
{ 
    return (*pf)(audit); 
} 
+0

謝謝你的解釋 – Patrick 2009-08-25 15:00:26

1

我做跟蹤一些非常相似,但使用stringstream。這確保所有第三方operator <<()和操縱器都能正常工作。我也使用desctructor而不是客戶寫操縱器。

class DebugStream 
{ 
public: 
    DebugStream(short level, const char * file, int line) { 
     sstream << "L" << level << "\t" << file << "\t" << line << "\t"; 
    } 
    ~DebugStream() { write(sstream.str()); } 

    std::ostream & stream() { return sstream; } 
private: 
    std::stringstream sstream; 

    DebugStream(const DebugStream &); 
    DebugStream & operator=(const DebugStream &); 
}; 

這則提供了一些宏:

#define DBG_ERROR if (1<=dbg_level()) DebugStream(1, __FILE__, __LINE__).stream() 
#define DBG_INFO if (2<=dbg_level()) DebugStream(2, __FILE__, __LINE__).stream() 

和代碼只是使用宏

DBG_INFO << "print some debug information"; 

你並不需要一個特定的寫操作器來刷新數據到日誌文件。當匿名DebugStream對象超出範圍(一旦控制離開該行),內容會自動寫入。

雖然我通常在這種情況下避免使用宏,但使用if語句意味着除非實際需要它,否則您沒有構建跟蹤行的開銷。

通過stream()方法返回ostream可使其適用於全局成員函數,因爲匿名對象不能作爲非const引用參數傳遞。