在引用这些指针时,我是如何意外覆盖的?

Kin*_*tor 6 c++ pointers

我保证今晚的最后一个问题.这些指针给我带来了严重的麻烦.

我有一个<Point名为Polygon 的std :: list >和一个std ::多边形列表定义如下:

typedef std::list<Point> Polygon; 
typedef std::list<Polygon> PolygonList; 

// List of all our polygons 
PolygonList polygonList; 
Run Code Online (Sandbox Code Playgroud)

我创建了下面的方法,尝试从(x,y)中删除最近的点,检查我的polygonList中的所有多边形.

void deleteNearestPoint(int x, int y)
{
    y = screenHeight - y;

    Polygon &closestPolygon = polygonList.front();
    Polygon::iterator closestPoint = closestPolygon.begin();

    float closestDistance = sqrt(pow(x - closestPoint->x, 2) + pow(y - closestPoint->y, 2));

    // Search PolygonList
    PolygonList::iterator listIter;
    Polygon::iterator iter;

    for(listIter = polygonList.begin(); listIter != polygonList.end(); listIter++)
    {
        Polygon &tempPolygon = *listIter;

        for(iter = tempPolygon.begin(); iter != tempPolygon.end(); iter++)
        {
            const float distance = sqrt(pow(x - iter->x, 2) + pow(y - iter->y, 2));

            if (distance < closestDistance)
            {
                closestPolygon = *listIter;
                closestPoint = iter;
                closestDistance = distance;
            }
        }

    }

    closestPolygon.erase(closestPoint);

    redraw();
}
Run Code Online (Sandbox Code Playgroud)

但是,在某个地方,我有一个指针或参考变量搞砸了我.此代码编译但以非常奇怪的方式执行.

我编写了一个调试语句,假设我的多边形列表中有3个多边形,如下所示:

多边形#:0
点:(448,43)
点:(469,177)
点:(374,123)
多边形#:1
点:(295,360)
点:(422,350)
点:(315,266)
点:(295,360)
多边形#:2
点:(143,202)
点:(301,203)
点:(222,100)
点:(143,202)

现在,让我说我尝试使用删除函数给它一个x/y接近点422,350所需的结果就是它只是从Polygon#1中删除那个点(422,350)但是我得到了这个:

多边形#:0
点:(295,360)
点:(422,350)
点:(315,266)
点:(295,360)
多边形#:1
点:(295,360)
点:(315,266)
点:(295,360)
多边形#:2
点:(143,202)
点:(301,203)
点:(222,100)
点:(143,202)

它确实删除了(422,350),但它也有一个奇怪的副作用,即在删除其点之前将Polygon#0覆盖到Polygon#1.

我知道我的方法中使用的指针或引用不正确.有人可以指出我可能会做的是什么造成这种情况?我认为这是因为我的&nearestPolygon被声明为引用,但如果我尝试将其设置为其他任何内容,则会出现编译错误.

MSN*_*MSN 6

不幸的是,你不能重新引用一个引用,即这一行:

nearestPolygon =*listIter;

将复制*listIterclosestPolygon,而不是重新引用*listIter.

编辑:要执行您想要的操作,您应该使用PolygonList::iterator而不是相应地Polygon &调整代码.


Dan*_*eer 4

其他答案已经指出了导致错误的原因。作为一般建议,我建议除了函数参数之外不要使用引用。语义很混乱,对于那些试图阅读你的代码的人来说也是如此。尝试重写为这样的内容(我没有测试代码):

void deleteNearestPoint(int x, int y)
{
    y = screenHeight - y;

    PolygonList::iterator closestPolygon = polygonList.begin();
    Polygon::iterator closestPoint = closestPolygon->begin();

    float closestDistance = sqrt(pow(x - closestPoint->x, 2) + pow(y - closestPoint->y, 2));

    // Search PolygonList
    PolygonList::iterator listIter;
    Polygon::iterator iter;

    for(listIter = polygonList.begin(); listIter != polygonList.end(); listIter++)
    {
        for(iter = listIter->begin(); iter != listIter->end(); iter++)
        {
            const float distance = sqrt(pow(x - iter->x, 2) + pow(y - iter->y, 2));

            if (distance < closestDistance)
            {
                closestPolygon = listIter;
                closestPoint = iter;
                closestDistance = distance;
            }
        }

    }

    closestPolygon->erase(closestPoint);

    redraw();
}
Run Code Online (Sandbox Code Playgroud)