這是不是太清楚你在做什麼,雖然它聽起來大致 正確。可以肯定的是:您所有的ostream
都提供了 便利的構造函數來創建並安裝您的streambuf
, 析構函數,並且可能還會執行rdbuf
至 句柄緩衝區的正確類型。假設這是真的: 在您的streambuf
中定義xsputn
純粹是一種優化。 您必須定義的關鍵功能是overflow
。 overflow
的最簡單的 實現只需要一個字符,並且 將其輸出到接收器。除此之外的一切都是優化:例如,您可以使用setp
來設置緩衝區,例如: ;如果你這樣做 ,那麼overflow
只會在緩衝區爲 已滿或請求刷新時才被調用。在這種情況下,您還必須使用 輸出緩衝區(使用pbase
和pptr
來獲取 地址)。 (該streambuf
基類初始化 指針創建一個0長度緩衝,所以overflow
將 呼籲每個字符),你可能 要覆蓋(很)特殊情況下的其他功能:
imbue
:如果出於某種原因,您需要使用語言環境。(請記住, 當前字符編碼是區域設置的一部分。)
setbuf
:允許客戶端代碼指定緩衝區。 (恕我直言,它的 通常不值得麻煩,但你可能有特殊的 要求。)
seekoff
:支持尋求。我從來沒有在 我的streambuf
s中使用過這個,所以我不能給出超出標準中可以讀取的 以外的任何信息。
sync
:調用flush時,應該將 緩衝區中的任何字符輸出到接收器。如果你永遠不會呼叫setp
(所以沒有 緩衝區),你總是同步,這可能是一個沒有操作。 overflow
或uflow
可以調用這個,或者兩者都可以調用一些 單獨的函數。 (關於sync
和uflow
之間的唯一區別是,如果有 緩衝uflow
纔會被調用,如果緩衝區是空的它永遠不會被調用。如果客戶端代碼刷新流 sync
將被調用。)
當寫我自己的流,除非性能決定 否則,我會保持簡單,並且只覆蓋overflow
。 如果性能決定了一個緩衝,我通常把代碼 刷新緩衝區到一個單獨的write(address, length)
功能,並實現沿線overflow
和sync
的 :
int MyStreambuf::overflow(int ch)
{
if (pbase() == NULL) {
// save one char for next overflow:
setp(buffer, buffer + bufferSize - 1);
if (ch != EOF) {
ch = sputc(ch);
} else {
ch = 0;
}
} else {
char* end = pptr();
if (ch != EOF) {
*end ++ = ch;
}
if (write(pbase(), end - pbase()) == failed) {
ch = EOF;
} else if (ch == EOF) {
ch = 0;
}
setp(buffer, buffer + bufferSize - 1);
}
return ch;
}
int sync()
{
return (pptr() == pbase()
|| write(pbase(), pptr() - pbase()) != failed)
? 0
: -1;
}
一般來說,我不會與xsputn
打擾,但如果您的客戶端 代碼輸出很多長字符串,它可能是有用的。 這樣的事情應該做的伎倆:
streamsize xsputn(char const* p, streamsize n)
{
streamsize results = 0;
if (pptr() == pbase()
|| write(pbase(), pptr() - pbase()) != failed) {
if (write(p, n) != failed) {
results = n;
}
}
setp(buffer, buffer + bufferSize - 1);
return results;
}
這基本上就是我現在所做的,我想知道的是,如果有無論如何要告訴溢出了多少次會被調用,或者當最後char已經過去了。例如,如果我做mystream << 1.3f;我會得到字符'1',然後''。然後'3'但在streabuf裏我無法知道有多少角色可以期待。當我得到3後,我想對緩衝區執行操作(呼叫另一個對象,讓它知道它已準備就緒) – 2011-04-13 15:16:53
代碼無法預先知道客戶端代碼要做什麼,或者它有多少次將被稱爲。你可以在'ostream'上設置'unitbuf':這會在每個'operator <<'(在'sentry'對象的析構函數)末尾調用sync。然後,您在'sync'中對緩衝區執行操作。 – 2011-04-13 17:20:07
aha!這完全是我需要的!把這個標記爲答案,但還是不能投票,一旦我得到足夠的代表,我會回來。非常感謝。 – 2011-04-13 18:34:29