jeudi 24 mai 2018

Trying to point with a smart pointer to an element in a vector

For my studies homework I had to make a directed weighted graph implementation using only smart pointers.

TransportationSystem class(Graph):

class TransportationSystem {
public:
    TransportationSystem(std::vector<std::string> _inputFiles);
    TransportationSystem(std::vector<std::string> _inputFiles, std::string _outputFile);
    TransportationSystem(std::vector<std::string> _inputFiles, std::string _outputFiles, std::string _configFile);

    void loadAll();
    void loadConfig();
    void loadFile(std::string fileName) throw();
    void printAllPaths();
    void printOutboundPath(std::string rootStationName);
    std::vector<Station>& getStations() { return stations;}

    class CouldNotOpenFileException {

    };

private:
    std::vector<std::string> inputFiles;
    std::string outputFile;
    std::string configFile;
    std::vector<Station> stations;

    int busTransitionTime;
    int tramTransitionTime;
    int sprinterTransitionTime;
    int railTransitionTime;

    bool defaultValues;

    int csTransitionTime;
    int sTransitionTime;
    int icTransitionTime;

    int getWaitingTimeByStationType(std::string _stationType);
    int getTransitionTimeByTransportationType(std::string _transportationType);
    void searchAndPrintPathByTransportationType(std::string transportationType, std::string rootName);
    void updateValue(std::string key, int value);
};

Station class(Vertex):

class Station {
public:
    Station(std::string _stationName, std::string _stationType, int _changingTime)
            :stationName(_stationName), stationType(_stationType), changingTime(_changingTime) {}
    void addRoad(Road& _road) {roads.push_back(_road);}
    std::vector<Road>& getRoads() { return roads;}
    std::string getStationName() const { return stationName;}
    bool operator==(const Station & obj2) const;
private:
    std::string stationName;
    std::string stationType;
    std::vector<Road> roads;
    int changingTime;
};

Road class(Edge):

class Road {
public:
    Road() {}
    Road(std::string _transportationType, std::string _source, std::string _destination, int _distance,
        int _transportationWaitingTime);
    Road(std::string _transportationType, std::string _source, std::string _destination, int _distance);
    void setDefaultValues(std::string transportationType, std::string sourceNode, std::string targetNode,
                          int distance);
    void setNonDefaultValues(std::string transportationType, std::string sourceNode, std::string targetNode,
                             int distance, int waitingTime);
    std::shared_ptr<Station*> nextStation;

    std::string getSourceNode() const { return source;}
    std::string getDestinationNode() const { return destination;}
    std::string getTransportationType() const { return transportationType;}
    int getDistance() { return distance;}
    bool operator==(const Road & obj2) const;
private:
    std::string transportationType;
    int distance;
    int transportationWaitingTime;
    std::string source;
    std::string destination;
};

So the station would be the vertex of the graph and the roads would be the edges.

As you can see in the Station class I hold a vector of Roads(edges) and each road holds a smart pointer(called nextStation) in order to point to the correspondant next Station.

In this function I load all the conections in the graph:

    void TransportationSystem::loadAll() {

    for (int i = 0; i < inputFiles.size(); ++i) {
        ifstream infile(inputFiles[i]);
        string sourceNode;
        string targetNode;
        int distance;
        string transportationType = getTransportationTypeByFileName(inputFiles[i]);
        string sourceStationType;
        string targetStationType;

        while (infile >> sourceNode >> targetNode >> distance) {
            // Making a new road
            Road r;
            if (defaultValues == true)
                r.setDefaultValues(transportationType, sourceNode, targetNode, distance);
            else
                r.setNonDefaultValues(transportationType, sourceNode, targetNode, distance, getTransitionTimeByTransportationType(transportationType));

            /* Here starts the trial scope */
            sourceStationType = getStationTypeBySourceNode(sourceNode);
            targetStationType = getStationTypeBySourceNode(targetNode);

            vector<Station>::iterator sourceNodeIt = find(stations.begin(), stations.end(), Station(sourceNode, sourceStationType, getWaitingTimeByStationType(sourceStationType)));
            vector<Station>::iterator targetNodeIt = find(stations.begin(), stations.end(), Station(targetNode, targetStationType, getWaitingTimeByStationType(targetStationType)));

            if (sourceNodeIt != stations.end() && targetNodeIt != stations.end()) {
                // Both Source node and Target node are on the stations vector
                // 1 - We have to point with the new road's pointer to the target node
                // 2 - insert the road to the source roads vector
                r.nextStation = make_shared<Station*>(&(*targetNodeIt));
                (*sourceNodeIt).addRoad(r);
            } else if (sourceNodeIt != stations.end() && targetNodeIt == stations.end()) {
                // Source node exists on the stations vector but target node doesnt exist in the station vector
                // 1 - So we create a new station for the target node
                // 2 - We point with the new road to the target node we just create
                // 3 - We insert the new road to the existing source node
                // 4 - We push the new target station to the station vector
                Station targetStation(targetNode, targetStationType, getWaitingTimeByStationType(targetStationType));
                r.nextStation = make_shared<Station*>(&targetStation);
                (*sourceNodeIt).addRoad(r);
                stations.push_back(targetStation);
                //sourceNodeIt = find(currentStations.begin(), currentStations.end(), Station(sourceNode, sourceStationType, getWaitingTimeByStationType(sourceStationType)));
            } else if (sourceNodeIt == stations.end() && targetNodeIt != stations.end()) {
                // Source node doesnt exist in the station vector but target vector exists
                // 1 - We have to point with the new road's pointer to the target node
                // 2 - We create a new station for the source node
                // 3 - We insert the new road to the new station we've just create
                // 4 - We push the new source station to the stations vector
                r.nextStation = make_shared<Station*>(&(*targetNodeIt));
                Station sourceStation(sourceNode, sourceStationType, getWaitingTimeByStationType(sourceStationType));
                sourceStation.addRoad(r);
                stations.push_back(sourceStation);
            } else {
                // Neither source node or vector doesn't exist in the station vector
                // 1 - We create a new station for the source node
                // 2 - We create a new station for the target node
                // 3 - We point with the new road to the target node
                // 4 - We insert the new road to the source node
                // 5 - We push both to the stations vector
                Station sourceStation(sourceNode, sourceStationType, getWaitingTimeByStationType(sourceStationType));
                Station targetStation(targetNode, targetStationType, getWaitingTimeByStationType(targetStationType));
                r.nextStation = make_shared<Station*>(&targetStation);
                sourceStation.addRoad(r);
                stations.push_back(sourceStation);
                stations.push_back(targetStation);
            }
        }
    }
}

By trying something like this:

r.nextStation = make_shared(&(*targetNodeIt));

I expected to be pointing to the actual Station in my stations vector, but while debugging I can see that if I change something on that specific station on the stations vector it won't change on the object that I pointed before.

Please help!

Aucun commentaire:

Enregistrer un commentaire