Class 在同一类构造函数中初始化静态std::vector时出现问题
如何在类中正确声明静态向量? 目前我有一行崩溃,因为向量初始化太晚了 示例一: 在示例2中,如果项目中的cpp文件具有此顺序编译顺序,则所有工作正常: classA.cpp main.cpp 如果订购此,我们将崩溃: main.cppClass 在同一类构造函数中初始化静态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; 第一个静态已初始化,但其构造函数尝试使用第二个静态,结果未定义 如果静态数据位于不同的文件
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
}