2013-07-16 72 views
2

我尋找相同類型的問題,但我沒有找到我的問題的答案(存在的問題): 應該選擇什麼類型的鉤子來控制列表中的對象? 我在指針和迭代器之間搖擺不定。鉤住std :: list中的對象。指針或迭代器?

容器在開始時填充,不應在此之後調整容器大小。鉤子是我用來在用戶心血來潮的時候在我的對象之間切換的方式,並且在我的算法中只能操作一個變量。

在所有情況下,我必須通過一個迭代器來找到正確的對象。但是哪一個是最佳實踐/使用?

// 10 object list 
std::list <Object> List(10); 

std::list <Object>::iterator it = List.begin(); 
Object *pt = NULL; 

// Select the 3rd object 
advance(it, 3); 
pt = &(*it); 

// Access to object member... 
it->member; 
pt->member; 

指針允許不訪問鄰居,與迭代器相反,但可能不安全。 什麼是最佳實踐?

+3

與大多數標準容器不同,在'std :: list'中,除非相應的元素被擦除,否則迭代器永遠不會失效,所以它與原始指針一樣(非)安全,但是如您所說,能夠從當前項目開始迭代。由於迭代器是非常輕量級的對象,選擇其中任何一個都不會對性能產生任何影響,所以它真的取決於您。 – syam

+1

如果容器在被填充後沒有被改變,並且考慮到你的例子中的訪問模式,你可以考慮使用一個你訪問的'std :: vector'變成'vec [3]',這會給你目的。 – ogni42

回答

1

將指針或迭代器存儲到容器中存在風險,因爲在使用它們時(即容器或數據發生更改),您可能會發現它們是無效的。

更廣泛和更健壯的方法可能是使用地圖而不是列表。每個值由(你喜歡什麼類型)的關鍵字標識,你可以很容易地存儲密鑰,並檢查他們是否是有效的在使用之前,例如:

std::map<int, std::string> data; 

// Add stuff to the map 
data[5] = "blah"; 
data[27] = "foo"; 

// Check if a key exists 
if (data.find(31) == data.end()) { 
    // Key 31 does NOT exist 
} else { 
    // Key 31 DOES exist 
} 

有一點要注意雖然是地圖按鍵值排序。這意味着如果元素的順序很重要,那麼你需要仔細選擇你的密鑰。

+0

我不熟悉map和set,但這似乎是hook函數的一個很好的替代品。我會用這種方式來看待,謝謝! – gfache

2

這取決於你想要做什麼與「鉤」。如果使用迭代器 ,則可以將其用作在列表中向前或向後移動 的起點。如果您使用指針,則您也可以指向列表之外的對象。最後, 取決於你期望你的代碼如何發展。

+0

鉤子的目標是提供一個連接對象列表和我的算法的常量對象。它允許根據用戶的意願在容器中的不同對象之間切換(在我的案例中,對象代表了一個長凳的配置)。 – gfache

0

在大多數情況下使用引用:

Object& ref = *it; 
ref.member 

它的行爲就像一個指針(可以隨意通過它周圍的功能),但你不能做就可以了指針算術(ref++實際上將呼籲operator++()目的)。你也不能從null初始化它(當你嘗試創建引用時會報告爲錯誤)。

有一點要記住,你仍然需要將對象分配到某處。如果說某個函數從列表中刪除了對象,則不應再使用ref

+0

引用在我的情況下是無用的,因爲鉤子是在程序的beginnig聲明的,即使列表是空的,然後設置'NULL'或'List.begin()',然後根據用戶的選擇進行賦值。 – gfache