在以下线程例程中:
void* Nibbler::moveRoutine(void* attr)
{
[...]
Nibbler* game = static_cast<Nibbler*>(attr);
while (game->_continue == true)
{
std::cout << game->_snake->_body.front()->getX() << std::endl; // display 0
std::cout << game->getDirection() << std::endl; // display 0
game->moveSnake();
std::cout << game->_snake->_body.front()->getX() << std::endl; // display 0
std::cout << game->getDirection() << std::endl; // display 42
}
}
[...]
}
我正在调用成员函数moveSnake(),它应该修改形成我蛇体的细胞的位置。
void Nibbler::moveSnake()
{
[...]
std::cout << this->_snake->_body.front()->getX() << std::endl; // display 0
this->_snake->_body.front()->setX(3);
this->_direction = 42;
std::cout << this->_snake->_body.front()->getX() << std::endl; // display 3
[...]
}
尽管我的两个坐标在我的moveSnake()函数中被有效修改,但当我回到我的例行程序时,它们不再是它们保持初始值。我不明白为什么会发生这种情况,因为如果我尝试在我的moveSnake()函数中修改我的类的任何其他值,则修改该实例并将该值保留在例程中。
Nibbler班:
class Nibbler
{
public :
[...]
void moveSnake();
static void* moveRoutine(void*);
private :
[...]
int _direction
Snake* _snake;
IGraphLib* _lib;
pthread_t _moveThread;
...
};
蛇:
class Snake
{
public :
[...]
std::vector<Cell*> _body;
};
最后是细胞:
class Cell
{
public :
void setX(const int&);
void setY(const int&);
int getX() const;
int getY() const;
Cell(const int&, const int&);
~Cell();
private :
int _x;
int _y;
};
cell.cpp代码:
void Cell::setX(const int& x)
{
this->_x = x;
}
void Cell::setY(const int& y)
{
this->_y = y;
}
int Cell::getX() const
{
return this->_x;
}
int Cell::getY() const
{
return this->_y;
}
Cell::Cell(const int& x, const int& y)
{
this->_x = x;
this->_y = y;
}
Cell::~Cell()
{}
答案 0 :(得分:2)
从表面上看,你的问题(“为什么这个成员什么时候不应该被修改?”)似乎是合理的。所展示的设计意图已经足够清晰,我认为它符合您的描述。但是,你的程序中的其他元素却合谋使其不是这样。
可能困扰你的一件事是Undefined Behavior。信不信由你,即便是最有经验的C ++开发人员偶尔会与UB发生冲突。此外,堆栈和堆损坏是非常容易导致非常难以隔离的问题的方法。你有几件事要转向,以便根除它:
如果您尚未使用调试器,那么这是您的第一步。如果您以前从未使用过,那么现在是您必须暂停一段时间并了解如何使用的时间。如果你计划超出这个水平,你会感激你的。
如果您在Windows上进行开发,则很有可能使用Visual Studio。调试器很可能很好地集成到您的IDE中。把它点起来!
如果您正在使用linux / BSD / OSX进行开发,则可以访问gdb
或XCode
,这两者都应该足够简单来解决此问题。阅读教程,观看视频,做任何事情并让调试器滚动。您可能很快发现您的代码一直在修改Snake
的一个实例并打印出另一个实例(或同样令人沮丧的内容)。
如果在使用调试器时无法复制问题条件,请恭喜!您找到了heisenbug。它可能表示race condition,仅此信息将帮助您了解问题的根源。