Here你會在下找到以下聲明哪個頭?:下面的方案如何保證只有一個對象cin,cout,...的定義?
最後,
<iostream>
提供了八種標準全局對象(CIN,COUT 等)。爲了正確執行此操作,此標頭還提供<istream>
和<ostream>
標頭的 內容,但不提供其他內容。標題的內容 樣子
#include <ostream>
#include <istream>
namespace std
{
extern istream cin;
extern ostream cout;
....
// this is explained below
static ios_base::Init __foo; // not its real name
}
現在,前面提到的運行時間延長:之前的任何自己的代碼使用它們的全局對象必須 初始化;這是由標準保證的 。像任何其他全局對象一樣,它們必須是 ,且只能初始化一次。這通常通過 這樣的構造完成,因此,標準中指定的嵌套類ios_base :: Init爲 。
它是如何工作的?由於標題包含在任何 代碼之前,所以__foo對象在任何對象之前構造。 (全局對象按聲明順序構建,並按相反順序銷燬)。構造函數首次運行時,將設置8個流對象。
我的問題:當我包括幾個.cpp
文件頭文件<iostream>
,請問上述擔保方案會有只是一個定義的對象cin
,cout
,等等?
「一個定義」不是很有趣 - 這只是(編譯的)標準庫的一部分。有趣的是「一次初始化」。 (我認爲這種技術被稱爲[「Schwartz計數器」](http://stackoverflow.com/q/9251763/596781)。) – 2013-02-16 10:20:27
AFAIK,'cout','cin'等人。對象只是在頭文件中聲明爲'extern',實際的定義在標準的lib文件中。現在,'ios_base :: Init'被聲明爲'static',因此每個翻譯單元都有自己的副本。 Init'對象的構造函數/析構函數進行某種引用計數,以瞭解何時初始化/銷燬標準流對象。至少這是[stdlibC++似乎這樣做](http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/include/std/iostream?view=markup)。 – jrok 2013-02-16 10:27:58
@jrok你說的一切都很清楚。當''包含在幾個'.cpp'文件中時,我不明白'ios_base :: Init'如何避免全局對象cin,cout,...的多重定義。 –
2013-02-16 10:35:15