gpt4 book ai didi

C++ 无法修改类的实例

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:45:12 24 4
gpt4 key购买 nike

在以下线程例程中:

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()
{}

最佳答案

从表面上看,您的问题(“为什么这个成员在应该修改的时候没有修改?”)似乎是合理的。所显示内容的设计意图足够清楚,我认为它与您所描述的相符。但是,您程序的其他元素合谋使它并非如此。

可能困扰您的一件事是 Undefined Behavior .信不信由你,即使是最有经验的 C++ 开发人员偶尔也会与 UB 发生冲突。此外,堆栈和堆损坏是导致极难隔离问题的极其简单的方法。为了根除它,你有几件事情要做:

调试器(从这里开始!)

  • 使用简单的单步调试器,您可以遍历代码并随时检查您的假设。设置断点,执行直到,检查内存/变量的状态,再次平分问题空间,迭代。

静态分析

  • 从编译器警告开始,一直到 lint 和复杂的商业工具,静态分析可以帮助指出“代码异味”,它不一定是 UB,但可能是死代码或您的代码可能不存在的其他地方你认为它做了什么。
  • 您是否忽略了您正在调用的库/操作系统返回的错误?在你的情况下,你似乎在直接操纵内存,但这是期望与现实不匹配的常见原因。
  • 你有rubber duck吗?方便吗?

动态分析

  • 诸如 Electric Fence/Purify/Valgrind(memcheck, helgrind)/Address-Sanitizer、Thread-Sanitizer/mudflaps 之类的工具可以帮助识别您在已分配内存之外写入内存的区域。

如果您还没有使用过调试器,那么这是您的第一步。如果您以前从未使用过,现在是您必须暂停一下并学习如何使用的时候了。如果你打算超越这个水平,你会庆幸你做到了。

如果您在 Windows 上进行开发,您很有可能正在使用 Visual Studio。调试器可能很好地集成到您的 IDE 中。开火!

如果您在 linux/BSD/OSX 上进行开发,您可以访问 gdbXCode,这两者都应该足够简单来解决这个问题。阅读教程,观看视频,尽一切努力让调试器运行起来。您可能会很快发现您的代码一直在修改 Snake 的一个实例并打印出另一个实例的内容(或类似的令人沮丧的事情)。

如果您在使用调试器时无法重现问题情况,恭喜!您找到了 heisenbug .它可能表示 race condition ,仅此信息就可以帮助您找出问题的根源。

关于C++ 无法修改类的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22811915/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com