2010-09-13 38 views
5

我正在開發一個將現有代碼移植到不同平臺的引擎。現有代碼是使用第三方API開發的,我的引擎將根據我的新平臺重新定義這些第三方API函數。我應該返回一個迭代器或指向STL容器中的元素的指針嗎?

下面的定義來自於API:

typedef unsigned long shape_handle;  
shape_handle make_new_shape(int type); 

我需要重新定義make_new_shape,我必須重新定義shape_handle的選項。

我定義這個結構(簡體):

struct Shape 
{ 
    int type 
}; 

make_new_shape調用者不關心Shape的基礎結構,它只是需要一個「處理」給它,這樣它可以調用函數如:

void `set_shape_color(myshape, RED);` 

其中myshape是形狀的句柄。

我的引擎將管理對象Shape的內存和其他要求,指示引擎應將Shape對象存儲在列表或其他可迭代容器中。

我的問題是,什麼是最安全的方式來表示這個句柄 - 如果Shape本身將存儲在一個std :: list - 一個迭代器,一個指針,一個索引?如果您嘗試訪問這些對象已被刪除後,所以也不是本質安全的

+2

你爲什麼選擇std :: list? – 2010-09-13 12:00:21

+0

@jk - 我需要能夠從容器的中間添加和移除'Shape'對象。 – BeeBand 2010-09-13 13:03:50

+0

你肯定不想重新定義shape_handle(或make_new_shape)。 – 2010-09-13 14:41:27

回答

3

問題的答案取決於你的表現:

  • std::list,使用iterator(不是指針),因爲iterator允許你刪除的元素不走整個列表。
  • std::mapboost::unordered_map,使用Key

,如果你使用的關聯容器您的設計將是非常強大的,因爲關聯容器給您查詢對象的存在的能力(當然)的,而不是調用未定義的行爲。

嘗試基準既mapunordered_map,看看哪一個是你的情況:)更快

6

既是一個迭代器或指針會做不好的東西。迭代器的優點是它可以用來訪問集合的其他成員。

所以,如果你只是想訪問你的形狀,然後指針將最簡單的。如果你想遍歷你的列表,然後使用迭代器。

索引是在自的std ::列表的列表無用不超載[]操作。

+1

+1:你是否提供訪問你的內部表示(迭代器)或不(指針)是最重要的區別。 – 2010-09-13 12:28:04

3

IIF內部表示將形狀的列表,然後指針和迭代是安全的。一旦分配了一個元素,就不會發生重定位。出於明顯的訪問性能原因,我不會推薦索引。 O(n)在列表的情況下。

如果您使用的載體,那麼就不要使用迭代器或指針,因爲元素可以當你超過載體容量搬遷,和你的指針/迭代器將變得無效。

如果你想有一個表示,而無論內部容器是安全的,然後創建指針的容器(列表/矢量)到你的形狀,形狀指針返回到客戶端。即使容器在內存中移動,Shape對象仍將保留在相同的位置。

3

迭代器並不比指針更安全,但他們比原始指針更好的診斷,如果您使用的是檢查了STL的實現!

例如,在一個調試版本中,如果你返回一個指向列表元素的指針,然後擦除那個列表元素,你就有一個懸掛指針。如果您訪問它,則會發生崩潰,並且您只能看到垃圾數據。這可能會讓我們很難弄清楚出了什麼問題。

如果您使用迭代器並且有一個檢查過的STL實現,只要您訪問迭代器到一個已擦除元素,就會得到類似「迭代器失效」的消息。那是因爲你抹去了它指向的元素。 Boom,你只是爲自己節省了大量的調試工作。

所以,不是O(n)表現的指數。指針和迭代器之間 - 總是迭代器!

相關問題