1

我正在使用 SDL 开发 RTS 游戏。我有一个木场类,其对象将从附近的树木中收集木材。在类中,我创建了一个名为 temp_trees 的向量,并作为构造函数的参数,我使用了一个传入的树对象向量。

林场建设者:

woodyard::woodyard(int x, int y, int HP, int id, vector<Tree> trees)
{
...
vector<Tree> temp_trees;
for(int i = 0; i < trees.size(); i++)
{
    if((trees[i].xPos - 100) / 50 >= x - 5 && (trees[i].xPos - 100) / 50 <= x + 4)
    {
        if((trees[i].yPos - 100) / 50 >= y - 5 && (trees[i].yPos - 100) / 50 <= y + 4)
        {
            temp_trees.push_back(trees[i]);
        }
    }
}

collect_control = 0;
no = 0;
}

collect_wood 函数:

void woodyard::collect_wood(){
if(no == 5)
{
 temp_trees[collect_control].drewno -= 1;
 if(temp_trees[collect_control].drewno <= 0){
 collect_control++;
 temp_trees.erase(temp_trees.begin());
}}


no++;
if(no >= 10){
  no = 0;
}}

程序刚启动就崩溃了。任何人都可以看到此代码中的任何错误吗?

PS:我想在构造函数中将元素从一个向量复制到另一个向量可能有问题。

4

2 回答 2

0

在woodyard 构造函数中,您要声明一个临时的、函数范围的变量“temp_trees”。

woodyard::woodyard(int x, int y, int HP, int id, vector<Tree> trees)
{
...
vector<Tree> temp_trees;

如果您有一个名为 temp_trees 的向量成员,则此声明将隐藏它。所以你的成员函数没有看到相同的向量:

void woodyard::collect_wood(){
if(no == 5)
{
 temp_trees[collect_control].drewno -= 1;

此外,如果没有看到其余代码,我不知道您如何确保向量中至少有“collect_control”成员。

#include <assert.h>
...
assert(collect_control < temp_trees.size());

或者如果您使用的是视觉工作室,您可以这样做

if(collect_control >= temp_trees.size())
    DebugBreak();

“size()”是一个从 1 开始的值,但数组索引运算符是从零开始的。这意味着,当向量中有一个条目时,它将是向量[0]。如果向量为空,则向量[0] 是非法的——它不存在。空性由大小为 0 表示。大小必须始终大于您尝试访问的元素索引。

于 2013-06-22T19:52:14.193 回答
0

构造函数不包含任何非法操作。

而collect_wood(),虽然难以理解,但没有包含任何使其崩溃的明显原因。

哪个是价值collect_control?你检查是不是< temp_trees.size()?请注意,temp_trees.size()由于您正在擦除元素,因此会不断变化。

擦除后可能collect_control不应该增加:所有元素都向后移动,并且擦除后的 collect_control 已经指向下一个元素。

注意:考虑到这temp_trees.erase(temp_trees.begin());是你可以用向量做的最低效的事情之一(删除第一个元素)。

于 2013-06-22T19:34:09.047 回答