2011-10-04 102 views
3

我正在重寫一個在學習STL之前由我編寫的通用庫。它一路使用C風格的數組。在許多地方有這樣的代碼:處理stl容器的大小

unsigned short maxbuffersize; // Maximum possible size of the buffer. Can be set by user. 
unsigned short buffersize; // Current size of the buffer. 
T *buffer; // The buffer itself. 

我做的第一件事就是改變這樣的代碼:

unsigned short maxbuffersize; 
unsigned short buffersize; 
std::vector<T> buffer; 

然後:

typedef unsigned short BufferSize; 
BufferSize maxbuffersize; 
BufferSize buffersize; 
std::vector<T> buffer; 

然後我感覺我正在做一件非常糟糕的事情,應該重新考慮我的編碼風格。起初,BufferSize對於一種類型來說似乎是一個非常糟糕的名字,但隨後出現了各種奇怪的問題。我如何命名大小類型?我應該使用自己的類型還是從std::vector<T>::size_type繼承?我應該緩存容器的大小還是一直使用size()?我應該允許用戶手動設置容器的最大尺寸,如果不是,我該如何檢查溢出?

我知道不可能有一種萬能的方法,因此我想聽聽其他編碼器和框架供應商使用的策略。我正在研究的圖書館是跨平臺的通用目的,旨在發佈到公共領域並使用數十年。謝謝。

+0

既然你要將它釋放到公有領域,我認爲你應該給你的程序一點點插件。 – Tom

+0

這是[Source engine console](http://developer.valvesoftware.com/wiki/Console)的克隆,但有一些限制(例如只有一個實例)被刪除。 – Lyberta

+0

王牌,如果你在互聯網上建立一個倉庫(如github) - 發佈鏈接 – Tom

回答

12

我認爲默認選擇應該是擺脫buffersizemaxbuffersize,並全程使用buffer.size()buffer.capacity()

我建議不要緩存大小,除非您有非常具體的原因來執行此操作,並使用探查器運行的硬數據。緩存會帶來額外的複雜性,並且緩存可能與真實事物保持同步。

最後,在您認爲有必要進行檢查的地方,您可以使用buffer.at(i)。如果i超出範圍,這將引發異常。

+0

緩衝「std :: vector」的大小完全是愚蠢的,因爲它保證了性能不變(即與元素數量無關)。據我所知(這些包括'std :: array','std :: string','std :: valarray') – rubenvb

+1

@rubenvb真的對於任何其他序列容器也是如此? (for size_t i = 0; i Tom

+0

命名約定呢?我認爲BufferSizeType是一個很好的例子,但是有些情況下索引被傳遞給用戶是不透明的,我不知道一個好的方法來解決這個問題。 – Lyberta

2

一般來說,我會建議使用迭代器來訪問您的數據。當你這樣做時,你通常不會明確地調用容器的大小。這也可以將你從一起使用std::vector中分離出來 - 並且讓你簡單地改變爲例如std::list,如果你稍後意識到這更適合你的需求。

當你使用迭代器時,對vector.size()的需求一般會大大減少。 (當你確實需要它使用buffer.size()buffer.capacity()作爲aix說)。

例如:

typedef unsigned short BufferSize; 
BufferSize maxbuffersize; 
BufferSize buffersize; 
std::vector<T> buffer; 
for(unsigned short i = 0; i< maxbuffersize;++i) 
{ 
    //do something with buffer[i]; 
} 

變得

struct do_something 
{ 
    void operator()(const T& t) 
    { 
    //do something with buffer[i] 
    } 
}; 
std::vector<T> buffer(maxbuffersize); 
std::for_each(buffer.begin(), buffer.end(), do_something()); 

這是一點點清潔器。

0

保留大小對於may結構很有用,但對於數組/向量來說有點多餘,因爲大小保證是最終索引+ 1。如果你擔心運行結束,像上面提到的迭代器方法將解決這個問題,以及大多數可能的比較大小等問題;

這是非常標準的定義您的所有類型和它們的大小在一個標頭中的API,它爲不同的平臺和編譯器設置它們......查看與它的LONG,ULONG,DWORD等定義的窗口。舊的「C」約定是以一個唯一的名稱或首字母縮寫(如MYAPI_SIZETYPE)作爲前綴。這很羅嗦,但避免了任何跨平臺混淆或編譯器問題。

+0

我把所有我的類型進入我自己的命名空間,並且從不使用''使用'來避免名稱衝突。 – Lyberta