【问题标题】:Is it guaranteed by the C++ standard that cin, cout, etc. will be created first and destroyed last?C++ 标准是否保证 cin、cout 等会先创建后销毁?
【发布时间】:2014-11-21 11:03:48
【问题描述】:

cincout,与基本流相关 - 标准中的任何地方都保证这些对象将首先创建并最后销毁吗?

这意味着非本地静态对象可以在其构造函数和析构函数中依赖它们(这些对象和基本流之间没有 ctor 竞争)。

【问题讨论】:

    标签: c++ c++11 stl


    【解决方案1】:

    保证在包含<iostream> 之后声明的任何静态对象之前创建它们,并且无论如何,在启动main 之前。它们在程序执行期间不会被销毁。

    包含标头具有声明ios_base::Init 类型的静态变量的效果,其创建确保标准流被初始化。

    如果你想要这个标准的:

    C++11 27.4.1 [iostream.objects.overview]/2:在第一次构造类 ios_base::Init 的对象之前或期间的某个时间构造对象并建立关联,并且无论如何,在 main 的主体开始执行之前。在程序执行期间对象不会被破坏。在翻译单元中包含<iostream> 的结果应如同<iostream> 定义了具有静态存储持续时间的ios_base::Init 实例。同样,整个程序的行为就好像至少有一个具有静态存储持续时间的ios_base::Init 实例。

    【讨论】:

    • main 不是唯一的东西,程序员会写。全局变量和静态变量也是候选对象。
    • @Ajay:确实,这就是为什么main 不是我唯一提到的原因。正如我所说,保证在包含<iostream> 之后声明的任何静态对象之前创建流。
    • 我不是说你错了迈克,但我怀疑。原因:我可能有多个标题,包含在正确的顺序(或不包含)。不能保证第一个标头会按照给定的顺序放入链接器/加载器的初始化阶段。还是有保证?如果不是,则包含 <iostream> 只不过是文本包含。是的,我知道流类的实际代码驻留在运行时库(DLL、SO 或静态库)中。如果是这种情况,是否可以保证首先初始化 DLL/SO/LIB 对象?再次,那里的订单保证是什么?
    • @Ajay:我已经准确地说明了保证是什么。如果您包含标头(保证在包含点插入其内容),则随后在同一翻译单元中声明的任何静态对象(因此库等与此无关)将在流之后初始化。如果您声明一个静态对象而不首先包含标头,则无法保证。
    • @hauron Mike 的回答给出了字面规则。我没有在回答中重复它们,因为它们已经被陈述过了。我之所以回答是因为我认为值得描述这些保证的限制,但如果没有 Mike 的保证,我的回答是不完整的。
    【解决方案2】:

    您的问题的简单答案是否定的。正如其他人指出的那样, 翻译单元中定义的对象保证 包括<iostream>,至少如果对象是在 包容。但这并不总是有帮助:您将 <iostream> 包含在 定义构造函数的翻译单元,不一定在 定义静态变量的那个。所以像下面这样的情况 是可能的:

    file1.hh

    class X
    {
    public:
        X();
    };
    

    file1.cc

    #include "file1.hh"
    #include <iostream>
    
    X::X()
    {
        std::cout << "Coucou, me voila!" << std::endl;
    }
    

    file2.cc

    #include "file1.hh"
    
    X anX;
    

    在这种情况下,anX 的构造函数很有可能是 在构造 std::cout 之前调用。

    为了安全起见:如果一个对象的构造函数可能是 用作静态变量想要使用任何标准流,它 应该可能声明一个ios_base::Init 类型的本地静态:

    X::X()
    {
        static ios_base::Init dummyForInitialization;
        std::cout << "Coucou, me voila!" << std::endl;
    }
    

    如果std::cout 在此构造函数被构造时尚未构造 调用,将在构造静态变量时进行。

    【讨论】:

    • 感谢有用的例子“假装”是 cout/cin 安全 :)
    • +1 反例。
    • 从实际的角度来看,这个答案更有用 - 它显示了一个示例以及如何解决问题。该问题询问了标准,但我确实相信这些答案共同构成了“完美答案”,因此我选择了 Mike 的答案,并为此投票。
    猜你喜欢
    • 2016-04-01
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多