迭代向量会返回相同的对象

时间:2017-01-15 20:45:17

标签: c++ vector

我试图通过创建一个小型迷宫生成器来学习C ++。为了促进这一点,我将一个Cell()列表以及x和y值存储在Maze()中的向量内(为了完整性,下面还包含了一些其他信息,但它们并不相关)。

将细胞存储在载体中,确定细胞的X和Y值,并在创建时传递给每个细胞。

我遇到的问题是每个单元格似乎都填充了相同的x和y值。

以下是相关代码:

vector<Cell*>  Maze::cells;
int Maze::width;
int Maze::height;

Maze::Maze(int w, int h)
{
    /* Set width and height */
    width     = w;
    height    = h;

    /* These variables keep track of our position in the maze as we generate it */
    int scan_w = 0;
    int scan_h = 0;

    /* Continue looping until we've visited all cells */
    /* Offset by one because the width starts at 1 while the scan is zero-based */ 
    for (int i = 0; i <= (width * height); i++)
    {
        cells.push_back(new Cell(scan_w,scan_h));

        cout << scan_w << "/" << scan_h << endl;
        scan_w = (i % w);
        if (scan_w == 0)
        {
            scan_h++;
        }
    }


    for(int i = 0; i <= cells.size(); i++) 
    {
        cout << "[" << cells[i]->x << ", " << cells[i]->y << "]  " << &cells[i] << endl;
    }
}

编辑:这是Cell类的相关部分

int         Cell::x;
int         Cell::y;

Cell::Cell(int location_x, int location_y)
{
    x = location_x;
    y = location_y;
}

此代码的输出(为简洁而截断)为:

Maze maze = Maze(50, 25);

0/0
0/1
1/1
2/1
3/1
4/1
5/1
6/1
7/1
8/1
9/1
...
40/25
41/25
42/25
43/25
44/25
45/25
46/25
47/25
48/25
49/25
[49, 25]  0x632f30
[49, 25]  0x632f38
[49, 25]  0x632f40
[49, 25]  0x632f48
[49, 25]  0x632f50
[49, 25]  0x632f58
[49, 25]  0x632f60
[49, 25]  0x632f68
...

以下是我的假设:

  • 根据输出,scan_w和scan_h按预期递增(就像从左到右,从上到下读表)。
  • 根据流程控制文档/教程,我的理解是第一个for循环正在从单元格的一个元素正确移动到下一个元素。
  • 根据documentation for vector's push_back member,我假设它正确地将每个新创建的单元格的引用插入到向量中。
  • 根据documentation for the [] operator for vectors,我的理解是,如果我访问单元格[0]和单元格[1],我将访问不同的对象(这可以通过打印对象的地址来确认,如上文)。

因此我无法理解为什么当任何给定的单元格与scan_w和scan_h对齐时,每个单元格的x和y值分别为49和25。

最后,我考虑过以下几点:

  • for循环可能正在读取同一个对象(通过打印对象的地址而反驳)。
  • 这可能是范围问题。我已经习惯了Python,所以我的假设是范围的工作方式相同,但我不熟悉C ++,知道这是否准确。
  • 这可能与Vector的运作方式有关(或多或少地被[]运算符上的文档所证实。)
  • 输出可能具有欺骗性/ scan_ incrementmentation代码可能有错误。这是最有可能的情况,但我还没能发现任何事情。可能短暂的休息和新鲜的眼睛可能会在这里显示出一些东西。

2 个答案:

答案 0 :(得分:1)

我在显示的代码中看到了多个错误。

for (int i = 0; i <= (width * height); i++)

这是迭代太多次了。例如,如果宽度和高度均为10,则将迭代i,设置范围为0到100 包含 ,或101个单元格,而不是100。 / p>

下一个问题是scan_wscan_h的计算不必要地复杂。这应该是一个简单的计算,使用简单的数学,并同时修复迭代错误:

for (int i = 0; i < (width * height); i++)
{
    int scan_w = i % width;
    int scan_h = i / width;
    cells.push_back(new Cell(scan_w,scan_h));
}

另一个错误在于:

for(int i = 0; i <= cells.size(); i++) 

与第一个错误相同的问题。在最后一次迭代中,i将等于cells.size()cells[i]将不存在,从而导致未定义的行为。

同样,迭代应该更正为:

for(int i = 0; i < cells.size(); i++) 

您可以先自行解决这些问题,然后检查结果是否符合您的预期,或者是否还有其他问题。

答案 1 :(得分:1)

考虑如何格式化Cell类的代码,只是一瞥。可能是x和y被定义为静态(否则你不会在任何地方写“int Cell:x;”......)?那么案例很清楚,因为那是成员定义静态的本质。解决方案是删除static关键字。