更新:
正如神经元所建议的那样,我尝试输出 vector 的地址,在整个程序中它是相同的。这意味着不会重复。在定义了Planet和Player之后,但在程序进入setup()和render()之前, vector 会以某种方式“重置”。是什么原因造成的?
更新2:
使用cout,我确定该错误发生在main()之前。因此,将构造全局Player和Planet对象,并将指向它们的指针添加到MasterEntityVector。然后,在main()启动之前(或在main()启动时,但在其任何部分执行之前),MasterEntityVector会“重置”,此后一切都会按预期运行。当MasterEntityVector是CircularEntity类的静态成员和MasterEntityVector是OpenGLLoopLogic.ccp中的全局变量时,都会发生此行为。是什么导致这种现象?我认为这可能与“静态初始化顺序惨败” http://www.parashift.com/c++-faq-lite/static-init-order.html有关,但问题似乎稍有不同(例如,我没有崩溃)。
更新3:
我不知道为什么它不起作用,但是我发现有人遇到相同的问题和解决方案。请参阅下面的答案。我将删除整个项目的内容(将问题缩小为原始大小),因为在链接中查看Alex的问题时,较大的项目似乎与该问题无关。

如果我的错误不重要,我谨向您致歉。我是一位C++初学者,对范围和多个文件项目的概念掌握得相对较差,因此尽管我花了很多时间来处理代码并在Internet上寻找答案,但我可能还是漏掉了一些明显的东西。
以下代码经过简化,目的是使我的问题更易于回答。
我正在使用代码块,C++,OpenGL(用于图形)和SDL(用于窗口)。
添加了cout行以进行故障排除,我将在下面提供输出。
问题是一个称为MasterEntityVector的全局 vector ,该 vector 应该包含指向仿真中所有“实体”的指针。在CircularEntity.ccp中声明它,在CircularEntity.h中带有一个外部变量。应该在实体的构造函数期间向其中添加指针。在OpenGLLoopLogic.ccp中,将在创建实体时将指针添加到MasterEntityVector中,但是然后,当我们开始进入init / setup / render函数时,它似乎要么被重置,要么被创建了第二个实例。如何停止这种不良行为?
CircularEntity.h:

#ifndef CIRCULARENTITY_H
#define CIRCULARENTITY_H

#include "LUtil.h"

class CircularEntity {
    public:
        CircularEntity(double x, double y, int r);
        double xpos, ypos;
        int radius;
        void Draw(double camxpos, double camypos);

};

extern std::vector<CircularEntity *> MasterEntityVector;  //contains pointers to ALL entities

#endif // CIRCULARENTITY_H
CircularEntity.ccp:
#include "CircularEntity.h"

std::vector<CircularEntity *> MasterEntityVector;  //contains pointers to ALL entities

CircularEntity::CircularEntity(double x, double y, int r) {
    radius = r;
    xpos = x;
    ypos = y;
    std::cout << "test 1" << std::endl;
    std::cout << MasterEntityVector.size() << std::endl;
    MasterEntityVector.push_back(this);
    std::cout << "test 2" << std::endl;
    std::cout << MasterEntityVector.size() << std::endl;
}

...
//irrelevant code removed
...
OpenGLLoopLogic.h:
#ifndef OPENGLLOOPLOGIC_H
#define OPENGLLOOPLOGIC_H

#include "MoveableCircular.h"

//Screen constants
const int SCREEN_WIDTH = 1800;
const int SCREEN_HEIGHT = 1000;

bool initGL();

void setup();

void update();

void render();

void handleKeys( unsigned char key, int x, int y );

#endif // OPENGLLOOPLOGIC_H
OpenGLLoopLogic.ccp:
#include "OpenGLLoopLogic.h"

//The projection scale
GLfloat gProjectionScale = 1.f;
MoveableCircular Player(200, 200, 0, 0, .05, 10);
CircularEntity Planet(0, 0, 100);

bool initGL()
{
    ...
    //irrelevant code removed
    ...
    setup();

    return true;
}

void setup() {
    CircularEntity Planet2(0, 0, 100);
    CircularEntity Planet3(0, 0, 100);
}

void velocityupdate()
{
    Player.Gravity(0,0,100);
}

void positionupdate()
{
    Player.PositionUpdate();
}

void update()
{
        velocityupdate();
        positionupdate();
}

void render()
{
    ...
    //irrelevant code removed
    ...
    for (int n=0; n<MasterEntityVector.size(); n += 1) {
        (*MasterEntityVector[n]).Draw(Player.xpos, Player.ypos);
        std::cout << MasterEntityVector.size() << std::endl;
    }

    ...
    //irrelevant code removed
    ...
}

void handleKeys( unsigned char key, int x, int y )
{
    ...
    //irrelevant code removed
    ...
}
我省略了几个文件,所以你们都不需要阅读很多不相关的代码:
MoveableCircular源和 header 与CircularEntity文件非常相似。 (cout的测试是3和4而不是1和2,并且MoveableCircular类继承自CirularEntity,它只有一个重新定义的构造函数)。
main.ccp调用init,然后有一个循环:处理键,更新然后渲染。
“包含树”中的文件“MoveableCirular.h”上方(我不知道正确的术语)与该问题无关,它们与该问题真正相关的唯一事情是“#包括“
输出为:
test 1
0
test 2
1
test 3
1
test 4
2
test 1
2
test 2
3
test 1
0
test 2
1
test 1
1
test 2
2
2
2
2
.
.
.
[infinite 2's]
从输出中可以看到,在构造Player和Planet对象时一切正常。
但是,当我们进入OpenGLLoopLogic函数(设置中为Planet2和Planet3,绘制代码渲染等)时,似乎“重置”或创建了MasterEntityVector的第二个副本。这种不良行为的原因是什么?
我已经尝试过的事情:
在MasterEntityVector之前的整个代码中添加“::”
命名空间的东西(尽管我对命名空间的了解和理解很薄弱,所以这仍然可能是问题的根源)。

最佳答案

我仍然不知道为什么我做错了什么,但这是指向相同问题的链接,以及针对有类似问题的人的解决方法:

Global vector emptying itself between calls?

请参阅ZeRemz的解决方案。

就我而言,我使用/添加了以下代码:

在CircularEntity.h中:

std::vector<CircularEntity *> &getMasterEntityVector();

在CircularEntity.ccp中:
std::vector<CircularEntity *> &getMasterEntityVector()
{
    static std::vector<CircularEntity *> s_vector;
    return s_vector;
}

我仍然不知道为什么我的原始实现(或者为什么链接中的Alex的原始实现)是错误的,而且我从来不喜欢不知道为什么,但是至少我们有一个解决方案!

关于c++ - 全局 vector 重置,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16764439/

10-12 20:43