在我学习STL之前,我正在重写一个由我编写的通用库。它一直使用C风格的数组。在许多地方都有这样的代码:
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 :(得分:12)
我认为默认选择应该是摆脱buffersize
和maxbuffersize
,并始终使用buffer.size()
和buffer.capacity()
。
我建议不要缓存大小,除非你有非常具体的理由这样做,使用分析器运行的硬数据支持。缓存会带来额外的复杂性以及缓存与真实事物同步的可能性。
最后,在您认为有必要进行检查的地方,您可以使用buffer.at(i)
。如果i
超出范围,这将抛出异常。
答案 1 :(得分: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());
有点干净。
答案 2 :(得分:0)
保持大小对于may结构很有用,但对于数组/向量来说有点多余,因为大小保证是最终的索引+ 1。如果你担心运行结束,那么提到的迭代器方法可以解决这个问题,以及关于可能的比较大小的大多数其他问题等等;
在标题中使用API为不同的平台和编译器设置所有类型及其大小是非常标准的...查看带有LONG,ULONG,DWORD等定义的窗口。旧的“ C“惯例是在它们前面加上一个唯一的名称或首字母,例如MYAPI_SIZETYPE。这是罗嗦但避免任何跨平台混淆或编译器问题。