-5
class ZombieLand : public Singleton<ZombieLand>
{
    DECLARE_SINGLETON(ZombieLand);
public:
    MachineState* world[19][19];
    bool map[19][19];

    MachineState* getField(int x, int y)
    {
        return world[x][y];
    }
void setWorld(MachineState state)
{

    world[state.x][state.y] = &state;
    map[state.x][state.y] = true;

}
};

struct MachineState
{
    template <typename MachineTraits>
    friend class Machine;

    enum Facing { UP, RIGHT, DOWN, LEFT};
    MachineState()
        : m_ProgramCounter(1)
        , m_ActionsTaken(0)
        , m_Facing(UP)
        , m_Test(false)
        , m_Memory(nullptr)
        ,x(0)
        ,y(0)
        ,point1(25, 10)
        ,point2(10, 40)
        ,point3(40, 40)
    { }

    int m_ProgramCounter;
    int m_ActionsTaken;
    Facing m_Facing;
    bool m_Test;
    bool m_occupied;
    int x;
    int y;
    Point point1;
    Point point2;
    Point point3;

    int GetActionsPerTurn() const throw() { return m_ActionsPerTurn; }
    int GetMaxMemory() const throw() {return m_MaxMemory; }
    bool GetTruth() const throw() { return m_InfectOnAttack; }
    void setPoint(Point p1, Point p2, Point p3)
    {
        point1=p1;
        point2=p2;
        point3=p3;
    }
};

我后来通过做调用 getField 函数

MachineState *Field1 = ZombieLand::get().getField(state.x, state.y-1 );

问题是当我尝试通过执行 Field1->getTruth() 访问成员时,它返回的是指针的地址而不是实际值(假或真)。我不明白为什么会这样

template <class T>
class Singleton
{
private:
    static T* _instance;
protected:
    Singleton() {}
public:
    static T& get()
    {
        if (_instance)
        {
            return *_instance;
        }
        else
        {
            _instance = new T();
            return *_instance;
        }
    }
};

if(ZombieLand::get().map[state.x+2][state.y] == true)
{
    MachineState *field3 = ZombieLand::get().getField(state.x+2, state.y);
        std::cout<<"FOUND FIELD"<<Field3->getTruth();
}

当这个 if 语句变为真时,它会在我的控制台上打印“FOUND FIELD 0246”

4

3 回答 3

2

由于我们没有两者的签名,get因此getField很难分辨。但也许尝试

*(ZombieLand::get().getField(state.x, state.y-1 ))

获取指针指向的值。

编辑

它有助于阅读代码,即

MachineState * 世界[19][19];

是一个二维指针数组。在这段代码中,没有任何地方给这些指针赋值,所以就目前而言,你很幸运,这东西没有死。

所以,

   MachineState *getField(int x, int y)
   {
    return world[x][y];
   }

正如函数签名所指定的那样!

但是在这段代码中,你在哪里给指针一个值或意义?

于 2013-04-27T08:30:30.860 回答
0

好的,现在我认为您终于发布了有问题的代码

class ZombieLand : public Singleton<ZombieLand>
{
    DECLARE_SINGLETON(ZombieLand);
public:
    MachineState* world[19][19];
    bool map[19][19];

    MachineState* getField(int x, int y)
    {
        return world[x][y];
    }
    void setWorld(MachineState state)
    {
        world[state.x][state.y] = &state;
        map[state.x][state.y] = true;
    }
};

这是未定义的行为,因为您将指针保存到局部变量statestate退出setWorld函数后变量会被销毁,因此您的数组world只是保存指向已销毁对象的指针,这就是您有垃圾值的原因。

在没有指针的情况下重写这个类。

class ZombieLand : public Singleton<ZombieLand>
{
    DECLARE_SINGLETON(ZombieLand);
public:
    MachineState world[19][19];
    bool map[19][19];

    MachineState* getField(int x, int y)
    {
        return &world[x][y];
    }
    void setWorld(const MachineState& state)
    {
        world[state.x][state.y] = state;
        map[state.x][state.y] = true;
    }
};

指针几乎总是一个坏主意,您应该尝试在没有它们的情况下编写代码。

至少最后到了那里。

于 2013-04-27T09:08:28.183 回答
0
void setWorld(MachineState state)
{
    world[state.x][state.y] = &state;
    map[state.x][state.y] = true;
}

您正在使用堆栈上超出范围并且在退出后不再有效的局部变量world的内存地址初始化数组的内容,从而使数组指向无效对象。稍后调用时,您会从当前调用堆栈中获取随机数据。setWorld()MachineStategetField()

如果您希望数组指向外部MachineState实例,则需要通过引用而不是按传递它们,以便获得原始对象的地址,而不是临时对象:

void setWorld(MachineState &state)
{
    world[state.x][state.y] = &state;
    map[state.x][state.y] = true;
}

否则,将数组更改为不再保存指针:

class ZombieLand : public Singleton<ZombieLand>
{
    DECLARE_SINGLETON(ZombieLand);
public:
    MachineState world[19][19];
    bool map[19][19];

    MachineState* getField(int x, int y)
    {
        return &world[x][y];
    }

    void setWorld(const MachineState &state)
    {
        world[state.x][state.y] = state;
        map[state.x][state.y] = true;
    }
};
于 2013-04-27T09:08:46.180 回答