哪些文件必须包含在 iostream 中
What files must iostream be included in?
我正在编写一个快速示例来演示全局对象的初始化/销毁。 在这样做的过程中,我遇到了以下难题。
一般而言,不应在头文件中包含头文件中代码不需要的任何头。 这有助于减少混淆和编译时间。
在我的示例中,我将构造函数和析构函数的定义从类定义中分离出来。 就我而言,它们是如此微不足道,以至于我可能只是内联它们,但这只是一个例子。
实际定义构造函数和析构函数的转换单元包括iostream
,以便它可以将调用输出到控制台。
问题是,当我们开始讨论在全局范围内声明我的类的实例时。 现在我遇到了初始化顺序和翻译单元。 翻译单元中全局变量的初始化顺序已明确定义。 全局变量从一个翻译单元到另一个转换单元的初始化顺序不太明确。 在我的示例中,它可以执行以下操作之一:
- 初始化第一个源文件
- ,然后初始化第二个源文件。 初始化第二个源文件
- ,然后初始化第一个源文件。
- 初始化第二个源文件。
24.4.1/2:对象 [std::cout 在我的例子中] 是在构造类 ios_base::Init
的对象之前或期间的某个时间构建的,并且在任何情况下都是在 main 主体开始执行之前构建的。在程序执行期间不会销毁对象。在翻译单元中包含<iostream>
的结果应<iostream>
定义具有静态存储持续时间的ios_base::Init
实例。同样,整个程序的行为就好像至少有一个具有静态存储持续时间的ios_base::Init
实例一样。
请注意,此段落调用了 like 规则,因此它不必创建 ios_base::Init
的实例,但它的行为必须像它一样。
假设编译器和标准库确实按照段落中指定的行为,并且不做不同但等效的事情,似乎对我的程序唯一有效的初始化顺序是初始化第一个源文件,然后初始化第二个源文件。 否则,在尝试使用它之前,std::cout 将不会初始化。
头文件:
#ifndef HEADER_H_
#define HEADER_H_
struct A {
A(const char*);
~A();
const char* v;
}
#endif
第一个源文件:
#include "header.h"
#include <iostream>
A::A(const char* val) : v{ val } {
std::cout << v << "n";
}
~A() {
std::cout << "~" << v << "n";
}
A a{ "a" };
A b{ "b" };
第二个源文件:
#include "header.h"
A c{ "c" };
A d{ "d" };
int main() {
}
在写这个问题时,我意识到答案包含在 3.6.2/4 中。
是否在main 的第一个语句之前完成具有静态存储持续时间的非局部变量的动态初始化是实现定义的。如果初始化推迟到第一个 main 语句之后的某个时间点,则应在第一次使用与要初始化的变量相同的翻译单元中定义的任何函数或变量之前进行初始化。
这意味着即使它决定只初始化第二个源文件,对 c
构造函数的调用也会导致第一个源文件在实际执行 c
的构造函数之前被初始化。 这保证了静态初始化完成的顺序为:
-
ios_base::Init
-
a
-
b
-
c
-
d
由于初始化顺序没有歧义,因此没有问题。
- 包含在 <initializer_list> <iostream>?
- 为什么在包含iostream时可以使用printf()?
- 为什么我必须在包含后写 std::cin <iostream>?
- 包含iostream导致不同的二进制文件
- C++ Boost-iostream:包含 filtering_streambuf.hpp 时出现神秘错误
- C++:为什么 std::greater<T>() 包含在 iostream 中?
- 包含<iostream>时"Undefined reference"错误
- 通过包含<iostream>头文件,它的所有 8 个函数是写入我的代码,还是只写入我在程序中使用的函数?
- 为什么包含iostream时此代码更快?
- 包含iostream时的自定义类时间的错误实例
- 运算符== 如果我包含<iostream>,则不编译
- 为什么我会得到一个包含<iostream.h>?
- 为什么 Xcode 4 在每个标头中都包含 iostream
- 已安装 Cygwin64,但在<iostream>日食中找不到未解析的包含内容
- 错误:'cout':未声明的标识符;虽然我已经在程序中包含了iostream头文件
- 如何避免重新包含在<iostream>多个文件中?
- 错误:标识符"cout"未定义。<iostream> 包含并使用命名空间 std;
- 为什么同时包含<iostream>和<fstream>
- 在 Xcode 中,当我包含 <iostream>时,似乎 stdlib.h 也被包含。为什么?
- 为什么iostream包含time.h ?