C ++标准是否保证cin,cout等会先创建并最后销毁?

时间:2014-11-21 11:03:49

标签: c++ c++11 stl

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

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

2 个答案:

答案 0 :(得分:7)

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

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

如果你想要Standardese:

  

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

答案 1 :(得分:7)

你问题的简单答案是否定的。正如其他人所指出的, 对翻译单元中定义的对象的保证 包括<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的构造函数很可能是。{1}} 在构造std::cout之前调用。

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

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

如果此构造函数是std::cout已经构造的话 调用时,它将构造静态变量。