C ++,指向对象的指针重置字符串变量的值

时间:2014-11-14 14:10:47

标签: c++ pointers

这是我在我的程序中使用的Map类的函数getValue(字符串名称) 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

我正在尝试创建一个指向从Map中检索的Node Object的指针 但返回的指针设置string name的值  空白可变。

在main.cpp文件中

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

以上代码的输出结果为

  

姓名,地址42,42

为什么省略名称字段?

1 个答案:

答案 0 :(得分:4)

问题是您的Map<ValueType>::getValue(string key)按值返回结果。当你这样做时

return (&nodes.getValue(name));

您将返回指向编译器创建的临时变量的指针,以存储getValue的结果。稍后取消引用此指针是未定义的行为,因为临时指向的对象在退出Graph::getNode(string name)函数时会被销毁。

要解决此问题,请通过引用从ValueType返回Map<ValueType>::getValue(string key)。这会将指针的生命周期限制为映射中相应元素的生命周期。当然,您需要确保在所有情况下都有一个有效的返回参考 - 具体而言,这不合法:return ValueType()。您需要创建一个静态变量来表示缺失值,并在找不到值时返回对它的引用。