list :: sort更改值c ++

Yan*_*oor 0 c++ sorting visual-studio

我在c ++中编写了一个不起作用的简单算法.我发现当我从我自己制作的自定义类中排序指向对象的列表时,它们会发生变化.或者更确切地说,列表更改为该类中的奇怪随机对象.

// ConsoleApplication45.cpp : Defines the entry point for the console application.
//


#include "stdafx.h"
#include <iostream>  
#include <map>
#include <list>
#include <math.h> 
using namespace std;  

class LocationNode;
class NodeMap;


class LocationNode
{
private:
    char name;
    int xLocation;
    int yLocation;
    //map<LocationNode*,int> neighbors;
    LocationNode* neighbors[100];
    int neighborWeight[100];
    int neighborCount; 
    LocationNode *previous;
    int score;

    int CalcDistance(LocationNode &dest)
    {
        return (int)sqrt(pow(dest.xLocation-xLocation,2) + pow(dest.yLocation-yLocation,2));
    }

public:
    int finalScore;

    bool operator<(LocationNode const& rhs) const
    {
       // Use whatever makes sense for your application.
       return (finalScore < rhs.finalScore);
    }
    bool operator==(LocationNode const& rhs) const
    {
       // Use whatever makes sense for your application.
       return (name == rhs.name && xLocation == rhs.xLocation && yLocation ==rhs.yLocation );
    }

    LocationNode(char name, int x, int y)
    {
        neighborCount = 0;
        this->name = name;
        this->xLocation = x;
        this->yLocation = y;
    }

    string GetPath()
    {
        if(previous!=NULL)
        {
            return string(1, name).append((*previous).GetPath());
        } else {
            return string(1, name);
        }
    }

    void Connect(LocationNode &other, int weight)
    {

        this->neighbors[neighborCount] = &other;
        this->neighborWeight[neighborCount] = weight;
    }

    void CalcScore(LocationNode &previous, LocationNode &dest)
    {
        int index = 0;
        for (int i = 0; i < neighborCount; i++)
        {
            if(neighbors[i] == &previous)
            {
                index = i;
            }
        }
        score = previous.score + neighborCount[&index];
        finalScore = previous.score + neighborCount[&index] + CalcDistance(dest);
    }
    void CalcNeighbors(LocationNode &dest)
    { 
        for (int i = 0; i < neighborCount; i++)
        {
            (*neighbors[i]).CalcScore(*this,dest);
        }

        /*for (pair<LocationNode,int> node : neighbors) 
        {
            node.first.CalcScore(*this,dest);
        }*/
    }

};

bool my_compare (LocationNode* a, LocationNode* b)
{
    return a->finalScore < b->finalScore;
}




class NodeMap 
{
private:
    static LocationNode& str;
    static LocationNode& dest;
    static LocationNode* node;
    static list<LocationNode*> nodes;
    static void loop(bool isFirst)
    {
        if(isFirst)
        {
            node = &str;
        }
        (*node).CalcNeighbors(dest);
        nodes.sort(my_compare);
        node = nodes.front();
    }
public:
    static string start()
    {
        Init();
        loop(true);
        while(node != &dest)
        {
            loop(false);
        }
        return dest.GetPath();
    }
    static void Init()
{
    nodes.clear();
    LocationNode A ('A',1,2);
    nodes.push_back(&A);
    LocationNode B ('B',7,1);
    nodes.push_back(&B);
    LocationNode C ('C',2,8);
    nodes.push_back(&C);
    LocationNode D ('D',4,3);
    nodes.push_back(&D);
    LocationNode E ('E',9,6);
    nodes.push_back(&E);
    LocationNode F ('F',1,2);
    nodes.push_back(&F);
    A.Connect(B,2);
    B.Connect(D,3);
    D.Connect(E,2);
    E.Connect(F,3);
    A.Connect(C,1);
    C.Connect(F,10);
    dest = F;
    str = A;
}
};

LocationNode& NodeMap::str =  *(new LocationNode('A',1,2));
LocationNode& NodeMap::dest = *(new LocationNode('F',1,2));
LocationNode* NodeMap::node =  &str;
list<LocationNode*> NodeMap::nodes;



int _tmain(int argc, _TCHAR* argv[])
{
    cout << &(NodeMap::start());
    cin.get();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在排序之前 https://i.imgur.com/nqU4m0j.png

排序后 https://i.imgur.com/eo2U3EB.png

对不起,我不能直接在这里发布图像我没有足够的声誉.

use*_*670 6

您正在推送指向堆栈分配对象的指针.在这些对象超出范围之后,这些nodes指针变得无效,因此容器最终会出现一堆悬空指针.您应该使用指向堆分配对象的指针填充此容器,以使它们有效.并且不要忘记稍后删除它们或使用智能指针.或者,您可以按值存储列表中的对象.请注意,与添加或删除新项目时std::vector,std::list不会使指向现有项目的指针无效.

list<LocationNode> nodes;
nodes.emplace_back('A', 1, 2);
Run Code Online (Sandbox Code Playgroud)