2014-11-14 52 views
0

以下是我在程序中使用的Map類中的函數getValue(字符串名稱) Map類將字符串存儲爲鍵並將ValueType存儲爲值。C++,指向對象的指針重置字符串變量的值

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文件我使用的地圖存儲節點通過有名稱映射(以下節點類的實現)。

的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 

我想創建一個指向正在從地圖
檢索到的節點對象,但返回的指針將變量的值設置爲空白。

在main.cpp中文件

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

上面代碼的輸出出來是

名稱,位置42,42

爲什麼名稱字段被省略?

+0

是否有原因將您的定義放入標題中? – user1810087 2014-11-14 14:14:26

+1

臨時/本地對象在函數作用域後被破壞... – P0W 2014-11-14 14:14:28

+0

無題注:函數「toString」的名稱令人困惑。這個名字暗示了一個字符串表示*返回*,而不是*打印*。我建議使用這些名稱:'print','debug'或'dump',並且我還建議將輸出流作爲參數,如果您願意,可以默認爲'std :: cout',但給用戶該選項轉儲到其他地方。或者你把它寫成一個'operator <<',使它與你在標準庫中打印東西的方式一致:'cout << * n'而不是'n-> print(cout)'。 – leemes 2014-11-14 14:53:11

回答

4

問題是您的Map<ValueType>::getValue(string key)按值返回結果。當你這樣做

return (&nodes.getValue(name)); 

你是返回一個指針由編譯器創建的存儲getValue結果的臨時變量。稍後解除引用該指針是未定義的行爲,因爲臨時指向的對象在退出Graph::getNode(string name)函數時會被銷燬。

要解決此問題,請從Map<ValueType>::getValue(string key)返回ValueType作爲參考。這會將指針的生存期限制爲映射中相應元素的生存期。當然,你需要確保在所有情況下都有一個有效的回報參考 - 具體來說,這不合法:return ValueType()。您需要創建一個靜態變量來表示缺少的值,並在找不到該值時返回對其的引用。