全局向量在呼叫之间清空?

时间:2011-09-24 21:29:28

标签: c++

我在标题中有一个向量,如下所示:

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到正确的向量中,并且地址都匹配。对于它的价值,这些东西在向量中的顺序并不重要。我不关心初始化顺序或任何事情。

2 个答案:

答案 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是一个全局变量 - 那么你就有问题了。