如何在类中更正声明静态向量? 目前我在一行崩溃,因为矢量初始化太晚了。
示例:
#include "stdafx.h"
#include <vector>
class A{
private:
int aValue;
public:
static std::vector<A*> listOfA;
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
}
};
A testA(1);
std::vector<A*> A::listOfA;
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
示例二:
classA.h
#include <vector>
class A{
private:
int aValue;
public:
static std::vector<A*> listOfA;
A(int i);
};
classA.cpp
#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
}
的main.cpp
#include "stdafx.h"
#include "classA.h"
A testA(1);
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
在示例2中,如果项目中的cpp文件具有此顺序(编译顺序),则一切正常: classA.cpp main.cpp中
如果订购此产品,我们会崩溃: main.cpp中 classA.cpp
答案 0 :(得分:0)
静态按照它们出现在文件中的顺序进行初始化,所以当你说:
时A testA(1);
std::vector<A*> A::listOfA;
初始化第一个静态,但是它的构造函数尝试使用第二个静态结果,但结果不确定。
如果静态文件位于不同的文件中,则初始化顺序未指定,因此如果您幸运或不幸,它可能会起作用。通常,不要编写依赖于静态初始化顺序的代码。
答案 1 :(得分:0)
引自:http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14 这个问题有很多解决方案,但是一个非常简单且完全可移植的解决方案是使用全局函数listOfA()替换全局对象listOfA,该函数通过引用返回对象。
std::vector<A*>& listOfA()
{
static std::vector<A*> ans;
return ans;
}
由于静态本地对象的构造是第一次控制流过它们的声明(仅),上面的新listOfA()语句只会发生一次:第一次调用listOfA()。每个后续调用都将返回相同的对象。然后你要做的就是将listOfA的用法改为listOfA():
int _tmain(int argc, _TCHAR* argv[])
{
// do stuff
A::listOfA().dostuff();
// do stuff
}
这被称为第一次使用构造上的构造,因为它只是这样:全局Fred对象是在第一次使用时构造的。
这种方法的缺点是对象永远不会被破坏。还有另一种技术可以解决这个问题,但需要谨慎使用,因为它会产生另一个(同样令人讨厌的)问题的可能性。
[编辑]抱歉nbt,没看到你已经链接到常见问题解答。他值得信任[/编辑]