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

hau*_*ron 6 c++ stl c++11

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

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

Mik*_*our 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具有静态存储持续时间的实例.

  • @Ajay:我已经确切地说了保证.如果包含标题(保证在包含点插入其内容),那么之后声明的任何静态对象,在同一个翻译单元中(因此库等与此无关)将在流之后初始化.如果在没有先包含标题的情况下声明静态对象,则无法保证. (4认同)

Jam*_*nze 7

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

file1.hh

class X
{
public:
    X();
};
Run Code Online (Sandbox Code Playgroud)

file1.cc

#include "file1.hh"
#include <iostream>

X::X()
{
    std::cout << "Coucou, me voila!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

file2.cc

#include "file1.hh"

X anX;
Run Code Online (Sandbox Code Playgroud)

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

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

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

如果std::cout在调用此构造函数时尚未构造,则将构造静态变量.