2011-06-11 29 views
1

我有一個簡單的類C++ STL地圖:刀片存儲空指針

class symbol_entry 
{ 
private: 
    static unsigned long uid; 

public: 
    std::string name; 
    std::string filename; 
    unsigned int line_number; 
    unsigned int column_number; 
    symbol_entry* parent_symbol; 
    std::map<const char*,symbol_entry*> child_symbols; 
    unsigned long type_flags; 

public: 
    symbol_entry(); 
    symbol_entry(const char* name, 
       const char* filename, 
       int line_number, 
       int column_number, 
       symbol_entry* parent_symbol, 
       unsigned long type_flags); 
    ~symbol_entry(); 

    symbol_entry* get_child(const char* name); 
    bool put_child(symbol_entry* child); 
}; 

這裏是symbol_entry執行:: put_child;

bool symbol_entry::put_child(symbol_entry* child) 
{ 
    if(child_symbols[child->name.c_str()]) 
     return false; 
    child_symbols.insert(std::make_pair(child->name.c_str(),child)); 
    return true; 
} 

每當我進行這樣的測試;

symbol_entry* tsym=new symbol_entry("test","$",0,0,0,0); 
symbol_entry* tcsym=new symbol_entry("test_child","$",0,0,0,0); 
tsym->put_child(tcsym); 
std::cout<<tsym->child_symbols.begin()->first<<" => "<<tsym->child_symbols.begin()->second<<std::endl; 

child_symbols.begin() - > second存儲空指針。我無法解決這個問題,並嘗試了許多變體,包括const和引用來取得利用。

+3

你將不得不發佈'put_child'的代碼。 – Puppy 2011-06-11 18:12:53

+0

剛剛在 – jmgun87 2011-06-11 18:16:34

+1

之上加註請注意,如果沒有將比較對象傳遞給您的'map'(請參閱http://www.sgi.com/tech/stl/Map.html上的示例),您的'const char *'鍵將會出現比較指針,而不是字符串。 – 2011-06-11 18:18:18

回答

5

child_symbols[child->name.c_str()]將始終創建並返回一個新的地圖條目(NULL值),然後child_symbols.insert(...)不會執行任何操作(因此地圖中的值保持爲NULL)。檢查開關是否已經在地圖上正確的方法是使用find

if (child_symbols.find(...) != child_symbols.end()) // already exists 
+0

完美。已修復它。謝謝! – jmgun87 2011-06-11 18:27:29

+0

@ jmgun87如果它適合您,請不要忘記接受答案! – 2011-06-11 18:28:54

+1

這是不正確的。它*將*總是創建一個NULL條目 - 在if語句中將被轉換爲'false'並且* not * return。 – Puppy 2011-06-11 19:05:25

4

您正在比較指針的價值。你需要比較他們指向。例如:

std::string s1 = "Hello World!"; 
std::string s2 = s1; 
s1.c_str() != s2.c_str() 

這就是爲什麼使用C-串的絕對不是認爲是一個C++適當編程 - std::string比較由值。

+0

我同意,因此我對這個問題發表了評論,但我不明白它會如何阻止他的例子工作。 – 2011-06-11 18:20:53

1

child_symbols[child->name.c_str()]不會做你認爲它做的事情:這會插入一個默認對象,在你的情況下每次都插入一個symbol_entry指針。我可能是錯的,但我認爲

if(child_symbols[child->name.c_str()]) 

將始終評估爲true因爲std::map將插入你的一個項目。

0

如果插圖已經存在於地圖中,插入將不會執行任何操作。您的支票child_symbols[child->name.c_str()]將在默認狀態下創建該元素,所以會發生這種情況。

你可以使用find,而不是做檢查,但insert已經有這個內置:

bool symbol_entry::put_child(symbol_entry* child) 
{ 
    return child_symbols.insert(std::make_pair(child->name,child)).second; 
} 

編輯:此外,什麼DeadMG說 - 使用std::string而不是const char*來修復

1

此:

child_symbols.insert(std::make_pair(child->name.c_str(),child)); 

是不是OK:您存儲c_str的結果(),這是不一個持久的價值。它給你一個指向一個C字符串的指針,該字符串在你調用它後立即生效,但是它對於以後的存儲和讀取無效。你應該讓你的地圖使用std :: string作爲它的關鍵類型。