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

Ale*_*lex 6 c++

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

extern std::vector<Foo> g_vector;
Run Code Online (Sandbox Code Playgroud)

在关联的cpp文件中我有这个:

std::vector<Foo> g_vector;
Run Code Online (Sandbox Code Playgroud)

我也有一个类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;
}
Run Code Online (Sandbox Code Playgroud)

如果我声明一个Bar函数内部,就像一个理智的人,它似乎工作正常.但是,如果我想声明Bar一个函数的外部,就会发生奇怪的事情.例如,我Bar在MyFile1.cpp和MyFile2.cpp中声明了一个,并且由于我在Bar中的cout语句,我可以看到Fooget被推入向量,但是当下一个Bar运行它的构造函数时,向量的大小再次为0.换句话说,我的输出是

0
1
0
1
Run Code Online (Sandbox Code Playgroud)

是什么赋予了?为了更加双重确定,我还尝试打印出来&g_vector以确保它实际上push_back是正确的向量,并且地址都匹配.对于它的价值,这些东西在向量中的顺序并不重要.我不关心初始化顺序或任何事情.

ZeR*_*emz 7

不确定问题究竟是什么,但我想以下模式将有助于解决它:定义全局变量的访问器并将其分配为静态函数变量,如下所示.

在头文件中:

std::vector<Foo> &getGlobalVector();
Run Code Online (Sandbox Code Playgroud)

在cpp文件中:

std::vector<Foo> &getGlobalVector()
{
  static std::vector<Foo> s_vector;
  return s_vector;
}
Run Code Online (Sandbox Code Playgroud)

这种模式的灵感来自于Andrei Alexandrescu在Modern C++设计中的"通用单例"实现.

每当我在保持现有应用程序的同时(或者在极少数情况下我实际上选择自己使用一个应用程序)时,我已经习惯于系统地使用这种模式,并且它可能有助于消除一些硬 - 在所述应用程序中重现错误.

无论如何,这应该有助于避免任何多初始化或初始化顺序相关的问题.


lit*_*adv 6

未定义全局值的初始化顺序.

在这里阅读有关静态初始化惨败的信息.

当你Bar在函数中声明时 - g_vector将在之前初始化,因为它承诺在程序运行之前初始化.如果Bar是全局变量 - 那么你就有问题了.