C++保证编译单元(.cpp文件)中的变量按照声明的顺序进行初始化。对于编译单元的数量,这个规则对每个编译单元单独起作用(我指的是类外的静态变量)。
但是,变量的初始化顺序在不同的编译单元中是未定义的。
我在哪里可以看到关于这个订单的一些解释,关于gcc和MSVC (我知道依赖于这是一个非常糟糕的想法-它只是为了理解我们在迁移到新的GCC主要和不同的操作系统时可能会遇到的遗留代码的问题)?
发布于 2008-10-17 07:30:17
我希望模块之间的构造函数顺序主要取决于将对象传递给链接器的顺序。
但是,GCC确实允许您为全局ctor执行use init_priority
to explicitly specify the ordering:
class Thingy
{
public:
Thingy(char*p) {printf(p);}
};
Thingy a("A");
Thingy b("B");
Thingy c("C");
输出'ABC‘正如你所期望的,但是
Thingy a __attribute__((init_priority(300))) ("A");
Thingy b __attribute__((init_priority(200))) ("B");
Thingy c __attribute__((init_priority(400))) ("C");
输出'BAC‘。
发布于 2008-10-17 07:41:03
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12 -此链接会移动。这个one更稳定,但你得四处看看。
编辑: osgx提供了更好的link。
发布于 2020-07-14 21:29:00
一个健壮的解决方案是使用一个getter函数,该函数返回对静态变量的引用。下面显示了一个简单的示例,它是我们的SDG Controller middleware中的一个复杂变体。
// Foo.h
class Foo {
public:
Foo() {}
static bool insertIntoBar(int number);
private:
static std::vector<int>& getBar();
};
// Foo.cpp
std::vector<int>& Foo::getBar() {
static std::vector<int> bar;
return bar;
}
bool Foo::insertIntoBar(int number) {
getBar().push_back(number);
return true;
}
// A.h
class A {
public:
A() {}
private:
static bool a1;
};
// A.cpp
bool A::a1 = Foo::insertIntoBar(22);
初始化将使用唯一的静态成员变量bool A::a1
。这将调用Foo::insertIntoBar(22)
。这将调用Foo::getBar()
,在返回对已初始化对象的引用之前,将进行静态std::vector<int>
变量的初始化。
如果static std::vector<int> bar
直接作为Foo class
的成员变量,则根据源文件的命名顺序,可能会在调用insertIntoBar()
之后初始化bar
,从而使程序崩溃。
如果多个静态成员变量在初始化期间调用insertIntoBar()
,则顺序将不依赖于源文件的名称,也就是随机的,但将确保在将任何值插入到std::vector<int>
之前对其进行初始化。
https://stackoverflow.com/questions/211237
复制相似问题