C ++, указатель на объект сбрасывает значения строковых переменных

0

Вот функция getValue (имя строки) из класса Map, который я использую в своей программе. Класс Map хранит строки как ключ и ValueType как значения.

template <typename ValueType>
  ValueType Map<ValueType>::getValue(string key)
    {
        if (containsKey(key))
            return (*this)[key];
        Error("Attempt to getValue for key which is not contained in map.");
        return ValueType(); // this code is never reached, but here to placate compiler
    }

В файле graph.h я использую Map для хранения узлов (реализация класса узлов ниже), отображаемых там именами.

Файл graph.h

#ifndef GRAPH_H
#define GRAPH_H

#include "node.h"
#include "map.h"

class Graph{
public :
    Graph();
    ~Graph();
    void addNode(string name, double x, double y);
    Node* getNode(string name);

private :
    Map<Node> nodes;

};

Graph::Graph(){}

Graph::~Graph(){}

void Graph::addNode(string name, double x, double y){
    if(!nodes.containsKey(name)){
        Node n(name, x, y);
        nodes.add(name, n);
    }
}

Node* Graph::getNode(string name){
    if(nodes.containsKey(name)){
        return (&nodes.getValue(name));
    }else{
        Error ("No node with that name exists");
    }
}

#endif

Класс узла

#ifndef NODE_H
#define NODE_H

class Node{

public:
    Node();
    ~Node();
    Node(string nodename, double nodeX, double nodeY);
    void toString();
private:
    string name;
    double x,y;

};

Node::Node(){}

Node::~Node(){}

Node::Node(string nodename, double nodeX, double nodeY){
    name = nodename;
    x = nodeX;
    y = nodeY;
}

void Node::toString(){
    cout<<"Name "<<name<<", Location "<<x<<", "<<y<<endl;
}


#endif

Я пытаюсь создать указатель на объект узла, который извлекается с карты
Но возвращаемый указатель задает значение имени string name varaible пустым.

В файле main.cpp

Graph g;
g.addNode("0COOL",42,42);
Node *n = g.getNode("0COOL");
n->toString();

Вывод вышеуказанного кода

Имя, местонахождение 42, 42

Почему поле имени опущено?

  • 0
    есть ли причина, по которой вы помещаете свои определения в заголовки?
  • 1
    временный / локальный объект уничтожается после области действия функции ...
Показать ещё 2 комментария
Теги:
pointers

1 ответ

4

Проблема в том, что ваша Map<ValueType>::getValue(string key) возвращает результат по значению. Когда вы это сделаете

return (&nodes.getValue(name));

вы возвращаете указатель на временную переменную, созданную компилятором для хранения результата getValue. Развертывание этого указателя позже является неопределенным поведением, поскольку объект, на который указывает временный объект, уничтожается при выходе из функции Graph::getNode(string name).

Чтобы устранить эту проблему, верните ValueType из Map<ValueType>::getValue(string key) по ссылке. Это ограничило бы время жизни указателя на время жизни соответствующего элемента на карте. Конечно, вам нужно убедиться, что во всех случаях есть верная ссылка на возврат - в частности, это не будет законным: return ValueType(). Вам нужно будет создать статическую переменную для представления отсутствующего значения и вернуть ссылку на нее, когда значение не будет найдено.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню