[英]C++ Static Initialization via Schwartz Counter
Schwartz计数器旨在确保在使用全局对象之前对其进行初始化。
请考虑使用下面显示的Schwartz计数器。
文件Foo.h:
class Foo
{
Foo::Foo();
};
文件Foo.cpp:
#include "Foo.h"
// Assume including Mystream.h provides access to myStream and that
// it causes creation of a file-static object that initializes
// myStream (aka a Schwartz counter).
#include "MyStream.h"
Foo::Foo()
{
myStream << "Hello world\n";
}
如果在main()启动后运行Foo :: Foo(),则保证myStream的使用是安全的(即myStream将在使用前初始化),因为注释中提到了文件静态初始化对象。
但是,假设在main()启动之前创建了Foo实例,如果它是全局的则会发生。 这显示在这里:
File Global.cpp:
#include "Foo.h"
Foo foo;
请注意,Global.cpp不会像Foo.cpp那样获得文件静态初始化对象 。 在这种情况下,Schwartz计数器如何确保在foo之前初始化MyStream初始化程序(以及MyStream对象本身)? 或者Schwartz计数器在这种情况下会失败吗?
“Schwartz计数器”的使用 (所谓的Jerry Schwartz之后,他设计了IOStreams库的基础知识,因为它现在已经成为标准;注意他不能因许多奇怪的选择而受到指责,因为它们被标记在原始设计上)可以导致在构造对象之前访问它们。 最明显的情况是在构建全局对象期间调用一个函数,该对象使用通过Schwartz计数器构建的自己的全局调用另一个翻译单元(我使用std::cout
作为全局由Schwartz计数器保护以保持例子简短):
// file a.h
void a();
// file a.cpp
#include <iostream>
void a() { std::cout << "a()\n"; }
// file b.cpp
#include <a.h>
struct b { b() { a(); } } bobject;
如果在文件中的全局对象b.cpp
是那些在文件之前建造a.cpp
,如果std::cout
通过与施瓦茨计数器构建a.cpp
是第一个实例,该代码将失败。 至少有两个原因导致Schwartz计数器不能正常工作:
char
缓冲区来实际定义对象(这些通常会被伪装成名称作为正确类型的对象)。 然而,在这两种情况下,事情都很混乱。 std::cout
的情况),这可能会导致显着的启动延迟:编写良好的代码通常不会使用任何全局初始化但是Schwartz计数器需要为每个需要加载的目标文件运行一段代码。 我个人已经得出结论,这种技术是一个很好的想法,但它在实践中不起作用。 我使用三种方法代替:
std::call_once()
初始化的函数静态对象是一个更好的选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.