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

发布于 11-10 02:12 字数 1302 浏览 3 评论 0原文

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

示例一

#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 文件具有此顺序(编译顺序),则一切正常: A类.cpp main.cpp

如果命令这个,我们会崩溃: 主程序 A类.cpp

How to correct declare static vector in class?
Currently I have crash on one line because vector initialize too late.

Sample one:

#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;
}

Sample two:

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;
}

In sample 2 if cpp files in project have this order(compilation order) all works fine:
classA.cpp
main.cpp

If order this, we have crash:
main.cpp
classA.cpp

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

瞄了个咪的2024-11-17 02:12:13

引用自: 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;
}

由于静态局部对象是在第一次控制流过其声明时构造的,因此上面的 new listOfA() 语句只会发生一次:第一次调用 listOfA() 时。每个后续调用都将返回相同的对象。然后您要做的就是将 listOfA 的用法更改为 listOfA():

int _tmain(int argc, _TCHAR* argv[])
{
    // do stuff
    A::listOfA().dostuff();
    // do stuff
}

这称为“首次使用时构造”习语,因为它就是这样做的:全局 Fred 对象是在第一次使用时构造的。

这种方法的缺点是对象永远不会被破坏。还有另一种技术可以解决这个问题,但需要谨慎使用,因为它可能会产生另一个(同样令人讨厌的)问题。

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

quoted from: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14
There are many solutions to this problem, but a very simple and completely portable solution is to replace the global object listOfA, with a global function, listOfA(), that returns the object by reference.

std::vector<A*>& listOfA()
{
    static std::vector<A*> ans;
    return ans;
}

Since static local objects are constructed the first time control flows over their declaration (only), the above new listOfA() statement will only happen once: the first time listOfA() is called. Every subsequent call will return the same object. Then all you do is change your usages of listOfA to listOfA():

int _tmain(int argc, _TCHAR* argv[])
{
    // do stuff
    A::listOfA().dostuff();
    // do stuff
}

This is called the Construct On First Use Idiom because it does just that: the global Fred object is constructed on its first use.

The downside of this approach is that the object is never destructed. There is another technique that answers this concern, but it needs to be used with care since it creates the possibility of another (equally nasty) problem.

[Edit] Sorry nbt, didn't see that you already linked to the faq. He deserves the credit[/Edit]

来世叙缘2024-11-17 02:12:13

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

A testA(1);
std::vector<A*> A::listOfA;

第一个静态已初始化,但其构造函数尝试使用第二个静态时,结果未定义。

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

Statics are initialised in the order they appear in a file, so when you say:

A testA(1);
std::vector<A*> A::listOfA;

the first static is initialised, but its constructor tries to use the second static, with undefined results.

If the statics are in different files, the order of initialisation is unspecified, so it may appear to work if you are lucky Or unlucky). In general, don't write code that depends on the order of initialisation of statics.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文