所以我正在制作一个带有传送和常用老鼠的蛇游戏.我有一个像这样运行的循环:
while(snake.alive() && miceEaten < micePerLevel)
{
displayInfo(lives, score, level, micePerLevel - miceEaten);
//some code
if(miceEaten())
{
//update score...
}
//more stuff...
}
Run Code Online (Sandbox Code Playgroud)
上述代码的问题是displayInfo在得分更新之前调用,因此在吃完鼠标之后,用户必须等到循环再次运行才能看到他的分数更新.所以我将这一行代码移到了函数的底部:
while(snake.alive() && miceEaten < micePerLevel)
{
//some code
if(miceEaten())
{
//update score...
}
//more stuff...
displayInfo(lives, score, level, micePerLevel - miceEaten);
}
Run Code Online (Sandbox Code Playgroud)
和传送停止工作!只要蛇到达传送,程序就会崩溃.并displayInfo使用以下代码:
stringstream s;
s << "LEVEL " << left << setw(12) << level << "LIVES: " << setw(12) << lives << "MICE LEFT: " << setw(12) << miceLeft
<< "SCORE: " << setw(13) << score;
printLine(0, s.str(), WHITEONBLUE);
Run Code Online (Sandbox Code Playgroud)
当printLine只有一个color_set,mvprintw和refresh().与传送无关.奇怪的.
所以我去了蛇功能,蛇从传送中获得了它的下一个位置:
body.push_back(teleports[overlap(next)]->teleportFrom(dir)); //next is a Location object
Run Code Online (Sandbox Code Playgroud)
当teleports[overlap(next)]->teleportFrom(dir)返回该位置的蛇是远距传送到.试图看看它崩溃的原因(可能Teleport是在屏幕外返回一些位置?),我在上面的行之前添加了以下3行:
Location l = teleports[overlap(next)]->teleportFrom(dir);
mvprintw(1, 0, "(%i, %i)", l.x, l.y);
refresh();
Run Code Online (Sandbox Code Playgroud)
问题就消失了!
不仅如此,我必须拥有这三条线.如果我发表评论mvprintw(1, 0, "(%i, %i)", l.x, l.y);,或者refresh();或两者,程序在到达传送时会像之前一样崩溃.
关于可能导致这种行为的任何想法?
更新:我尝试删除所有警告(主要是关于有符号/无符号数字比较的警告),但到目前为止只剩下1个警告:
warning: reference to local variable 'other' returned
Run Code Online (Sandbox Code Playgroud)
和代码:
Location& Location::operator = (Location other)
{
if(this == &other)
return other;
x = other.x;
y = other.y;
return *this;
}
Run Code Online (Sandbox Code Playgroud)
我该怎么做才能修复此警告?
像这样建立你的赋值运算符:
你应该总是返回*this(即使它们相等).但他们永远不会因为你创建一个本地副本(所以这不是你的错误).
Location& Location::operator = (Location const& other)
{
// Does it really matter if you assign to self?
x = other.x;
y = other.y;
return *this;
}
Run Code Online (Sandbox Code Playgroud)
对于这样一个简单的类,标准副本和交换似乎有点过分.
PS.您应该修复所有警告(即使它们像无符号不匹配一样简单).如果你不修复它们,你就会对它们的效力免疫,并且不会发现真正的问题,因为它被你忽略的警告所包围.所以修复它们(aI总是打开标志,使编译器将所有警告视为错误,以便在有任何警告时代码不会编译).
实现赋值运算符的正确方法(或最常用的好方法).是使用复制和交换习语:
// notice the parameter is passed by value (i.e. a copy).
// So the copy part is aromatically taken care of here.
// So now you just need tom implement the swap() part of the idiom.
Location& Location::operator = (Location other)
{
this->swap(other);
return *this;
}
void Location::swap(Location& other)
{
std::swap(x, other.x);
std::swap(y, other.y);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
840 次 |
| 最近记录: |