关于std::cout,为什么使用"extern"比"singleton pattern"
About std::cout, why use "extern" rether than "singleton pattern"
我阅读了第 04 项提到的有效C++
通过将非本地静态对象与本地静态对象重新放置,避免跨翻译单元的初始化顺序问题。
我认为"全局且只有一个对象"应该是单例模式,而不是我阅读此项目后的外部对象。
例如 I/O 对象(std::cout(
但是std::cout似乎是外部对象。(http://www.cplusplus.com/reference/iostream/cout/(
我对此感到困惑。
编辑:添加代码
我从这本书中捕获了一些代码。
首先是糟糕的代码:
class FileSystem {
// from your library’s header file
public:
...std::size_t numDisks( ) const;
// one of many member functions...
};
extern FileSystem tfs;
在不同翻译单元中定义的非本地静态对象的初始化相对顺序是不确定的。
所以当我调用 tfs 时,上述代码可能是错误的。
因为 tfs 可能无法完成初始化。
重新命令代码:
class FileSystem { ... }; // as before
FileSystem& tfs()
{
static FileSystem fs;
return fs;
}
class Directory { ... };// as beforeDirectory::Directory( params )
Directory::Directory( params ) // as before, except references to tfs are
//now to tfs( )
{
...
std::size_t disks = tfs().numDisks( );
...
}
Directory& tempDir()
{
static Directory td(params);
return td;
}
使用 extern
变量允许(主观上(更好的语法
std::cout << stuff;
强调标准流是唯一对象,而不是某些函数调用的结果。由于流式处理旨在完成流对象,因此使用对象表示法可以更好地与流对象相关联。
至于静态初始化顺序惨败,标准库通过使用施瓦茨计数器技术进行初始化来避免它。初始化按明确定义的顺序进行,因为包含 iostream
会将类型为 Init
的特殊全局对象添加到包含 TU。对象的构造函数在流首次使用之前处理流的初始化,无论第一次使用在哪里。
因为C++选择了更精细的方法,获得了直接对象访问的效率和简单性,并且仍然避免了静态初始化顺序的惨败。
如何?
c++ 标准流实际上不是静态初始化的。相反,#include <iostream>
定义了一个类型 std::ios_base::Init
的全局静态对象,它管理全局引用计数,并随之管理C++流的初始化。
或者至少,它是这样指定的,但总是有假设规则。
相关文章:
- Visual Studio 2015:Extern "C" 和 "export" 关键字
- 为什么在全局范围内使用"extern int a"似乎不行?
- C++ Singleton - Prevent ::instance() to variable
- 如何使用extern类
- 自动重复 extern "C"函数中的类构造函数采用的相同参数
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 使用说明符 extern 声明的C++中的标识符链接
- 可视化编译与 C++ 中的 Extern 变量
- 是否可以在不使用 decltype 的情况下推断先前定义的 extern 变量的类型
- 如何使用默认值将枚举声明为 extern
- 如何与 Cheerp/js 中的 extern 变量接口?
- 如何将 Python 字符串传递给 C++ (extern C) 函数
- 从 exe 和 dll 访问静态库中的 extern 变量
- "extern"声明以及带有和不带参数列表的类模板实例的后续定义
- 既然我们有内联变量,extern const 还有用吗?
- 在命名空间 c++ 中正确声明 extern 变量
- 尝试使用 extern "C" 调用 C 中的C++方法,得到"undefined reference to"对象的链接器错误
- Extern "C"错误在'int'之前'asm'或'__attribute__'
- Singleton ofstram:已创建但未写入的文件
- 关于std::cout,为什么使用"extern"比"singleton pattern"