【发布时间】:2014-11-21 11:03:48
【问题描述】:
cin,cout,与基本流相关 - 标准中的任何地方都保证这些对象将首先创建并最后销毁吗?
这意味着非本地静态对象可以在其构造函数和析构函数中依赖它们(这些对象和基本流之间没有 ctor 竞争)。
【问题讨论】:
cin,cout,与基本流相关 - 标准中的任何地方都保证这些对象将首先创建并最后销毁吗?
这意味着非本地静态对象可以在其构造函数和析构函数中依赖它们(这些对象和基本流之间没有 ctor 竞争)。
【问题讨论】:
保证在包含<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 不是唯一的东西,程序员会写。全局变量和静态变量也是候选对象。
main 不是我唯一提到的原因。正如我所说,保证在包含<iostream> 之后声明的任何静态对象之前创建流。
<iostream> 只不过是文本包含。是的,我知道流类的实际代码驻留在运行时库(DLL、SO 或静态库)中。如果是这种情况,是否可以保证首先初始化 DLL/SO/LIB 对象?再次,那里的订单保证是什么?
您的问题的简单答案是否定的。正如其他人指出的那样,
翻译单元中定义的对象有保证
包括<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 在此构造函数被构造时尚未构造
调用,将在构造静态变量时进行。
【讨论】: