2012-03-17 73 views
5

我真的想成爲一個更好的程序員,並且製作更多的模塊化,有組織的代碼。用C++編寫一個簡單的面向對象的圖形

作爲一個練習,我試圖在C++中用STL做一個非常簡單的Graph類。在下面的代碼中,我的Node對象不能編譯because the commented line results in a reference to a reference in STL

#include <set> 

class KeyComparable 
{ 
public: 
    int key; 
}; 

bool operator <(const KeyComparable & lhs, const KeyComparable & rhs) 
{ 
    return lhs.key < rhs.key; 
} 

class Node : public KeyComparable 
{ 
public: 
    // the following line prevents compilation 
    // std::set<Node &> adjacent; 
}; 

我想邊緣存儲在set(由key),因爲它允許通過鍵快速去除的邊。如果我要存儲list<Node*>,那可以正常工作,但不允許通過key快速刪除。

如果我使用std::set<Node>,通過邊緣所做的更改只會改變本地副本(實際上並不是相鄰的Node)。如果我使用std::set<Node*>,我不相信<運算符將工作,因爲它將在指針本身上運行,而不是它們索引的內存。

我認爲包裝引用或指針在另一個類,可能是我的KeyComparable類(根據鏈接的頁面,這是如何提升處理它)。

或者,我可以存儲std::list<Node*>std::map<int, iterator>' of locations in the std :: list`。我不確定在更改列表時迭代器是否會保持有效。

以前,這裏的一切都只是指針,我會手動處理所有的數據結構。但我真的很想停止使用我使用的每種語言編程C -style,並且實際上成爲一名優秀的程序員。

你認爲是什麼最好方式來處理這個問題?非常感謝。

回答

9

正如你所推斷的,你不能在STL容器中存儲引用,因爲存儲的項目的要求之一是它們是可分配的。這與你爲什麼不能在STL容器中存儲數組的原因是一樣的。如果沒有至少一個用戶定義的類型,您也不能重載運算符,這使得看起來您不能在STL類中存儲指針時進行自定義比較...

但是,您仍然可以使用std::set的指針,如果你給set自定義比較函子:

struct NodePtrCompare { 
    bool operator()(const Node* left, const Node* right) const { 
     return left->key < right->key; 
    } 
}; 

std::set<Node*, NodePtrCompare> adjacent; 

而且像你想你仍然key得到快速清除。

+0

+1好答案。除了比函數指針更好的語法之外,是否還有將比較函數包裝在結構中的其他好處? – user 2012-03-18 02:05:34

+0

@Oliver不是我所知道的,只是這種情況下唯一的方法。儘管可以的話,我更喜歡全局可訪問的'operator <',因爲它可以在不需要實例化'struct'的情況下進行比較。 – 2012-03-18 04:09:58