c++ - 下面的方案如何保证对象 cin、cout、...只有一个定义?

标签 c++ initialization iostream

Here您会在 Which header ? 下找到以下语句:

Finally, <iostream> provides the eight standard global objects (cin, cout, etc). To do this correctly, this header also provides the contents of the <istream> and <ostream> headers, but nothing else. The contents of this header look like

#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
}

Now, the runtime penalty mentioned previously: the global objects must be initialized before any of your own code uses them; this is guaranteed by the standard. Like any other global object, they must be initialized once and only once. This is typically done with a construct like the one above, and the nested class ios_base::Init is specified in the standard for just this reason.

How does it work? Because the header is included before any of your code, the __foo object is constructed before any of your objects. (Global objects are built in the order in which they are declared, and destroyed in reverse order.) The first time the constructor runs, the eight stream objects are set up.

我的问题:当我包含头文件时 <iostream>在几个.cpp文件,上面的方案如何保证对象的只有一个定义cin , cout等等……?

最佳答案

它并不能真正保证这一点。一个定义问题通过简单地在作为库的一部分的 .cpp 文件中定义一次流对象来解决。问题中的代码仅包含标准流的声明

保证的是对象在使用前将被初始化。 C++ 中全局对象的一个​​问题是,虽然它们 在每个 .cpp 文件中按顺序初始化,但我们不知道链接器将对象从不同文件放入的顺序。如果一个对象在另一个对象被初始化之前尝试使用另一个对象,并且我们不知道确切的顺序,这可能会导致问题 - 参见 Static initialization order fiasco .

这里使用的一种变通方法是在 header 中放置一个 Init 对象来声明流对象。因为在使用流之前必须包含 header ,所以我们知道这个 Init 对象将位于文件的顶部,因此在可能使用流的其他对象之前构造。

现在,Init 类的构造函数负责流对象的初始化。这必须尽早完成,而且只能做一次。究竟如何留给每个实现,但代码暗示使用一个计数器来跟踪创建的 Init 对象的数量(并且可能会特别处理第一个对象)。

这只是执行此操作的一种方法,仅使用标准语言。一些实现还有其他技巧,比如 #pragma s 或 init_priority指令说服链接器将库代码放在用户代码之前。在那种情况下,它只是神奇地工作,而不使用 Init 类。

关于c++ - 下面的方案如何保证对象 cin、cout、...只有一个定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14909173/

相关文章:

c++ - 如何声明和初始化类中的静态成员?

c - 局部变量与全局变量

c# - 使用 TFS SDK 从 TFS 获取所有文件夹

c++ - 在 C++ 中创建一个 iostream 对象

c++ - Com 线程/单元行为与编码工厂不一致

c++ - 多重继承 : same variable name

c++ - "inline function need to be DEFINED in all tranlation units"背后的基本原理是什么?

c++ - 如何为 friend 函数中定义的类授予友元?

c++ - 函数中int变量初始化失败

C++ 流与 C 风格的 IO?