C++作用域结束后指针引用丢失

3
我遇到了一个非常奇怪的错误,在离开for循环范围后,即使在类头中声明了包含对象的数组,我也无法访问指针在循环期间所指向的任何内容。
以下是代码的基本结构: Class CTile{ /*Code*/ };
Class CMap  
{  
    public:  
        CTile** tiles;  
        CMap();  
}

CMap::CMap()  
{  
    int lines = 10;
    int cols = 10;
    tiles = new CTile*[lines];  
    for(int i = 0 ; i (lower than) lines;++)  
    {  
        this->tiles[i] = new CTile[cols];  
    }  
    for(int curLine = 0; curLine (lower than) lines ; curLine++)  
        for(int curCol = 0; curCol (lower than) cols; curCol++)  
        {
            CTile me = this->tiles[curLine][curCol];
            me.setType(1);
            //do whatever I need, and inside the loop everything works.  
        }  
    int a = this->tiles[2][2].getType(); // a gets a really weird number 
    this->tiles[2][2].setType(10); // crashes the program

}

有人知道可能出了什么问题吗?


@Luke B:你意识到一个 std::vector< std::vector<Tile> > 可以使得大部分代码变得非常简单,而你只是使用那些指针是因为你喜欢调试噩梦和重复造轮子吗……我希望如此? - Matthieu M.
@Matthieu,我以前见过使用那种推理的情况。个人而言,我更喜欢一种命名约定,清楚地表示哪些变量是成员变量,哪些不是。 - Mark Ransom
@Mark:我也喜欢一种命名约定,它可以清晰地表明属性(在工作中通常使用下划线 _ 或在家中使用 m 前缀)。但为了区分方法和函数,我只是使用 this - Matthieu M.
@Matthieu,我发现将新值添加到多维数组比向量的向量更容易,除非有一种更简单的方法,而不是声明一个新向量并将其推回到第一个向量中。 - Luke B.
@Mark 是的,我知道 this-> 是多余的,但我更喜欢在所有东西上使用前缀。 - Luke B.
显示剩余4条评论
2个回答

4
CTile me = this->tiles[curLine][curCol];

这应该是

CTile& me = this->tiles[curLine][curCol];
me.setType(1);

为什么会发生这种情况呢?因为您复制了CTile,而不是创建对二维数组中的CTile的引用。 现在您可能会发现崩溃已经移动到me.setType(1)语句。


顺便提一下,因为您没有使用成员变量的命名约定(例如mTiles),我很欣赏您使用显式的this->tiles来强调tiles是一个成员变量。语法高亮将比您的大脑更快地将其带到您的视线中,以便快速注意到“tiles”不是传递给函数的局部变量或参数。 - Andy Finkenstadt
现在代码能正常工作了,谢谢你! - Luke B.

4
CTile  me = this->tiles[curLine][curCol];

这里有一个问题。 me 是原始对象 tiles[curLine][curCol] 的一个副本,所以无论你对 me 做什么操作,都不会反映在原始对象上。即使你执行 me.setType(1),原始对象也不会改变。我相信你不想这样。
所以解决方法是:使用引用,如下:
CTile & me = this->tiles[curLine][curCol];
  //  ^ note this
me.setType(1);

或者更好的方法是,您可以简单地执行以下操作:
tiles[curLine][curCol].setType(1); //"this" is implicit!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接