2010-09-23 70 views
1

iostream對象cin,cout,cerr和clog是在iostream頭文件中聲明的對象。我知道在一些編譯器中可能會嘗試在構造它們之前使用這些iostream對象,所以在某些情況下它們必須受到「靜態初始化命令失敗」的影響。在那些使用std :: cout等總是安全的編譯器中,這些對象是如何實際構建的?它涉及到底層的編譯器魔術還是原則上可以用標準C++來完成?iostream對象如何實現cin,cout,cerr和clog?

std :: cout等似乎是全局變量或單身:爲什麼全局變量和單身通常被認爲是邪惡的,但似乎不是在這種特殊情況下?

+0

靜態**初始化**命令失敗? – 2010-09-23 17:23:04

+0

如果編譯器標準庫編寫者不知道他們在做什麼,他們將會受到慘敗。所謂的Fiasco對於沒有意識到問題的沒有經驗的開發者來說只是一個問題。有許多技巧可以保證相對順序,並且確保在第一次使用之前創建std :: cin(和family)很簡單。不要把C++ FAQ中的所有內容都當成文字。 – 2010-09-23 20:16:51

+0

@Eugen Constantin Dinca:感謝您的發現;我相應地編輯了我的問題。 – 2010-09-23 20:20:48

回答

5

沒有編譯器的魔力。

IIRC,標準的實現是在頭文件中定義一個全局常量對象。在每個翻譯單元中包含該標題,就創建了一個這樣的對象。它的構造函數增加一個計數器,它的析構函數減少它。當從0遞增到1時,控制檯流對象被創建,當從1遞減到0時,它們被銷燬。

+1

這個習語也有一個名字:http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter – Cubbi 2010-09-23 17:28:16

+0

謝謝 - 我沒有意識到漂亮的/施瓦茨計數器的成語。 – 2010-09-23 20:27:44