我不太確定我得到的情況,但它聽起來像是你想有一個代理:
class LogSingleton
{
public:
LogSingleton& instance() { /* ... */ }
void lock(); // lock mutex
void unlock(); // unlock mutex
template <typename T>
friend LogSingleton& operator<<(LogSingleton& pLog, const T& pX)
{
// needs to be locked first
assert(is_locked());
/* output pX however */
return pLog;
}
};
class LogProxy
{
public:
LogProxy()
{
// manage lock in proxy
LogSingleton::instance().lock();
}
~LogProxy()
{
LogSingleton::instance().unlock();
}
};
// forward input into the proxy to the log, knowing it's locked
template <typename T>
LogProxy& operator<<(LogProxy& pProxy, const T& pX)
{
LogSingleton::instance() << pX;
return pProxy;
}
// now expose proxy
typedef LogProxy log;
而且你應該這樣做:
log() << "its locked now" << "and the temporary will die" << "here ->";
鎖定在做構造函數和析構函數,並在最後調用析構函數。
正如Tony正確指出的那樣,這會持續不必要的鎖定。該鎖僅用於「最終」輸出到LogSingleton
。想象一下:
log() << "this next function takes 5 minutes"
<< my_utterly_crappy_function() << "ouch";
沒有記錄互斥鎖被鎖定了很長時間。更好的辦法是緩衝輸出,然後立即輸出:
class LogProxy
{
public:
~LogProxy()
{
// manage lock in proxy
LogSingleton::instance().lock();
// no-throw, or wrap mutex use in a scoped-lock
LogSingleton::instance() << mBuffer.rdbuf();
LogSingleton::instance().unlock();
}
// buffer output
template <typename T>
friend LogProxy& operator<<(LogProxy& pProxy, const T& pX)
{
mBuffer << pX;
return pProxy;
}
private:
std::ostringstream mBuffer;
};
現在,直到緩衝區準備好輸出,纔會獲取鎖。
如果你放一點源代碼,比如如何調用記錄器,這將有所幫助。錯誤消息的一般格式是什麼,以及您使用的是什麼類型。從你的問題,它可以是std :: string,stream或字符數組。 – 2010-08-25 21:55:44
記錄器被設計爲處理std :: string和const char *它同時處理 – joy 2010-08-26 18:06:32