我在标题中有一个向量,如下所示:
extern std::vector<Foo> g_vector;
在关联的cpp文件中,我有:
std::vector<Foo> g_vector;
我还有一个班级Bar
,在它的构造函数中,它会向g_vector
添加一些内容,如下所示:
Bar::Bar(/* stuff */)
{
// do things
std::cout << g_vector.size() << std::endl;
g_vector.push_back(somefoo);
std::cout << g_vector.size() << std::endl;
}
如果我在一个函数内声明Bar
,就像一个理智的人,它似乎工作正常。但是,如果我想在函数之外声明Bar
,就会发生奇怪的事情。例如,我在MyFile1.cpp和MyFile2.cpp中声明了Bar
,并且由于我在Bar中的cout语句,我可以看到Foo
被推入向量,但是当下一个{ {1}}运行其构造函数,向量的大小再次为0。换句话说,我的输出是
Bar
是什么给出的?为了更加双重确定,我还尝试打印0
1
0
1
以确保它实际上是&g_vector
到正确的向量中,并且地址都匹配。对于它的价值,这些东西在向量中的顺序并不重要。我不关心初始化顺序或任何事情。
答案 0 :(得分:7)
不确定问题究竟是什么,但我想以下模式将有助于解决它:定义全局变量的访问器并将其分配为静态函数变量,如下所示。
在头文件中:
std::vector<Foo> &getGlobalVector();
在cpp文件中:
std::vector<Foo> &getGlobalVector()
{
static std::vector<Foo> s_vector;
return s_vector;
}
这种模式的灵感来自于Andrei Alexandrescu在Modern C ++设计中的“通用单例”实现。
我习惯于在保留现有应用程序时(或在极少数情况下我实际选择自己使用一个应用程序)时,系统地使用此模式,这可能有助于消除一对在所述应用程序中难以重现的错误。
无论如何,这应该有助于避免任何多初始化或初始化顺序相关的问题。
答案 1 :(得分:6)
未定义全局值的初始化顺序。
请在此处阅读static initialization fiasco。
在函数中声明Bar
时,g_vector
将在之前初始化,因为它承诺在程序运行之前进行初始化。如果Bar
是一个全局变量 - 那么你就有问题了。