在什么情况下以及为什么需要这样做:
class ios_base::Init {
static int init_cnt; // internal static counter (for exposition only)
public:
Init();
~Init();
}
从以下网站获取:cpluplus.com-ios_base::init
我读了描述并思考了一下,但这并没有多大帮助。。。
这是静态初始化顺序失败的解决方法。从本质上讲,如果你想使用静态初始化器中的全局流对象,你可以调用它来确保它们都是及时构建的。我熟悉的运行时已经正确地做到了这一点,但从技术上讲,这并不能保证。
(另请注意,从C++11开始,它是有保证的。)
需要它们来确保标准iostream对象,如std::cout
。基本上标准iostream对象保证由CCD_ 2的第一构造函数已经完成的时间。(init_cnt
成员是实现)此外,标准规定包括<iostream>
声明ios_base::Init
的静态实例(或表现得像这样),所以如果你写:
#include <iostream>
class X
{
public:
X() { std::cout << "something";
};
X anXwithStaticLifetime;
你保证std::cout
将在则运行CCD_ 7的构造函数。
当然,这只适用于一个翻译单元。如果您在标题中定义("X.hh"):
class X
{
public:
X();
};
然后在两个不同的翻译单元中:
#include "X.hh"
#include <iostream>
X::X()
{
std::cout << "something";
}
和:
#include "X.hh"
X anXwithStaticLifetime;
std::cout
很可能不会在执行构造函数时构造。通常的方式确保这是为了定义ios_base::Init
的本地实例在构造函数中:
X::X()
{
static ios_base::Init toEnsureInitialization;
std::cout << "something";
}
在实践中,大多数实现都使用额外的技巧降低风险。但据我所知,没有一个是100%,根据你的链接方式,你仍然会遇到问题。但是,如果你按照通常的方式做事,它们就不会发生。使用结果很多程序员没有意识到风险不要做必要的声明(而且它几乎总是有效的无论如何)。