Class 在同一类构造函数中初始化静态std::vector时出现问题

Class 在同一类构造函数中初始化静态std::vector时出现问题,class,visual-c++,vector,crash,initialization,Class,Visual C++,Vector,Crash,Initialization,如何在类中正确声明静态向量? 目前我有一行崩溃,因为向量初始化太晚了 示例一: 在示例2中,如果项目中的cpp文件具有此顺序编译顺序,则所有工作正常: classA.cpp main.cpp 如果订购此,我们将崩溃: main.cpp classA.cpp静态数据是按照它们在文件中出现的顺序初始化的,因此当您说: A testA(1); std::vector<A*> A::listOfA; 第一个静态已初始化,但其构造函数尝试使用第二个静态,结果未定义 如果静态数据位于不同的文件

如何在类中正确声明静态向量? 目前我有一行崩溃,因为向量初始化太晚了

示例一:

在示例2中,如果项目中的cpp文件具有此顺序编译顺序,则所有工作正常: classA.cpp main.cpp

如果订购此,我们将崩溃: main.cpp
classA.cpp

静态数据是按照它们在文件中出现的顺序初始化的,因此当您说:

A testA(1);
std::vector<A*> A::listOfA;
第一个静态已初始化,但其构造函数尝试使用第二个静态,结果未定义

如果静态数据位于不同的文件中,则初始化顺序未指定,因此如果幸运或不幸,它可能会起作用。一般来说,不要编写依赖于静态初始化顺序的代码。

引自: 这个问题有很多解决方案,但一个非常简单且完全可移植的解决方案是用一个全局函数listOfA替换全局对象listOfA,该函数通过引用返回对象

std::vector<A*>& listOfA()
{
    static std::vector<A*> ans;
    return ans;
}
这被称为“第一次使用时构造”习惯用法,因为它只是这样做的:全局Fred对象是在第一次使用时构造的

这种方法的缺点是对象永远不会被破坏。还有另一种技术可以解决这个问题,但需要谨慎使用,因为它可能会造成另一个同样严重的问题


[编辑]抱歉,nbt,没有看到您已经链接到常见问题解答。他值得表扬[/Edit]

如何在不同的文件中修改类以实现良好的初始化?不要修改它,只是不要这样做。但是,如果您交换初始化顺序,您的第一个示例将起作用。在实际代码中,它包含不同的文件,一个文件使用类,另一个文件使用类,您可以在堆栈上创建,而不是在全局函数中创建堆本地静态对象并返回它。销毁问题将通过标准静态对象销毁来处理。这就是所谓的懒惰初始化:是的,回到它。我仔细考虑了这个问题,然后回答了另一个问题。我发布的内容用于保证多个静态变量的静态初始化顺序,而正常的静态变量可以正常工作。编辑我的答案…我建议阅读更多关于静态初始化顺序失败的内容
#include "stdafx.h"
#include "classA.h"

std::vector<A*> A::listOfA;

A::A(int i)
{
  aValue = i;
  A::listOfA.push_back(this); // !!! HERE crash in release mode only, in debug mode items add to vector, but remove when vector initialize
}
#include "stdafx.h"
#include "classA.h"

A testA(1);

int _tmain(int argc, _TCHAR* argv[])
{
    return 0;
}
A testA(1);
std::vector<A*> A::listOfA;
std::vector<A*>& listOfA()
{
    static std::vector<A*> ans;
    return ans;
}
int _tmain(int argc, _TCHAR* argv[])
{
    // do stuff
    A::listOfA().dostuff();
    // do stuff
}