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-&gt; getTruth()来访问成员时,它返回指针的地址而不是实际值(false或true)。我不明白为什么会发生这种情况
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语句变为true时,它会在我的控制台上打印“FOUND FIELD 0246”
答案 0 :(得分:2)
由于我们没有get
和getField
的签名,因此很难说清楚。
但也许试试
*(ZombieLand::get().getField(state.x, state.y-1 ))
获取指针指向的值。
修改强>
有助于阅读代码,即
MachineState * world [19] [19];
是一个2D指针数组。在这段代码中没有任何地方给出一个值的指针,因此它就是幸运的是,这件事不仅仅会死亡。
因此,
MachineState *getField(int x, int y)
{
return world[x][y];
}
由功能的签名指定!
但是在这段代码中你给指针一个值或含义?
答案 1 :(得分: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;
}
};
这是未定义的行为,因为您将指针保存到局部变量state
。退出state
函数后,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;
}
};
指针几乎总是一个坏主意,你应该尝试在没有它们的情况下编写代码。
至少到目前为止。
答案 2 :(得分:0)
void setWorld(MachineState state)
{
world[state.x][state.y] = &state;
map[state.x][state.y] = true;
}
您正在初始化world
数组的内容,其中包含超出范围的本地变量的内存地址,并且在setWorld()
之后不再有效退出,使数组指向无效的MachineState
个对象。稍后调用getField()
时,您将从当前调用堆栈中获取随机数据。
如果您希望数组指向外部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;
}
};