自定义向量STL容器中的clear()存在问题 < P>加速C++中的一个例子,我创建了一个定制的STL容器,它是一个简化版本的 STD::vector < /C> >,称为 VEC>代码>。一切都进行得很顺利,直到成功之后,我尝试添加一个Vec::clear()来清除向量
以下是最新的类定义(仅与此问题相关的部分): 由于某种原因,自定义向量STL容器中的clear()存在问题 < P>加速C++中的一个例子,我创建了一个定制的STL容器,它是一个简化版本的 STD::vector < /C> >,称为 VEC>代码>。一切都进行得很顺利,直到成功之后,我尝试添加一个Vec::clear()来清除向量,c++,stl,stdvector,C++,Stl,Stdvector,以下是最新的类定义(仅与此问题相关的部分): 由于某种原因,clear()会关闭限制指针。当它甚至没有修改它时,这怎么可能呢。代码看起来很简单,但我看不出我遗漏了什么 谢谢 这并不难清除() 将向量返回到初始状态。(将limit也设置为NULL并释放缓冲区内存,比较data=avail=limit=0;与data=avail=0;) 让它变空,但不要收缩。(将数据保持原样,但将avail设置为data(avail=data) 这些规则中没有一条得到执行。(您的first版本不正确)这就是您获
clear()
会关闭限制
指针。当它甚至没有修改它时,这怎么可能呢。代码看起来很简单,但我看不出我遗漏了什么
谢谢 这并不难<代码>清除()
- 将向量返回到初始状态。(将
也设置为NULL并释放缓冲区内存,比较limit
与data=avail=limit=0;
)data=avail=0;
- 让它变空,但不要收缩。(将
数据保持原样,但将
设置为avail
(data
)avail=data
数据。清除时,您只带走可用(已分配)元素,缓冲区(数据
)保持不变
您应该替换data=avail=0代码>带有avail=数据代码>错误。。limit
指针在您的输出中是相同的。我知道。所以我计算容量的方法可能是错误的。如何将data
设置为零(表示一个空向量),并且仍然具有等于128的容量,就像std::vector所做的那样?容量不是向量的大小。容量是指在不增加的情况下可以容纳的元素数量。因此,当size==0时,容量不一定是0@Andrey,我理解大小和容量之间的区别。我希望大小为0,容量为128,就像std::vector在这种情况下所做的一样。谢谢你的回答。我按照你和安德烈的建议设置了avail=data
。然而,在这种情况下,在v.clear()之前,大小=100,容量=128,而在它之后,大小=0,容量=28。这并没有模仿std::vector的行为,在本例中,清除后它的大小为0,容量为128。怎样才能得到类似的行为?谢谢!我认为,您的第二个建议更接近于od std::vector的行为。然而,当我做出改变时,我仍然无法获得这种行为(见我对GMan的评论)。
template <class T>
class Vec {
public:
Vec() { create(); }
size_type size() const { return avail - data; }
size_type capacity() const { return limit - data; }
void clear();
// operators that return iterators
iterator begin() { return data; }
const_iterator begin() const { return data; }
iterator end() { return avail; }
const_iterator end() const { return avail; }
void push_back( const T& val ) {
if ( avail == limit ) grow();
unchecked_append( val );
}
private:
iterator data; // points to beginning of data
iterator avail; // points to end of initialized data
iterator limit; // points to end of data
std::allocator<T> alloc; // object to handle data allocation
void create();
// functions to support push_back()
void grow();
void unchecked_append( const T& );
};
// Creates an empty vector.
template <class T>
void Vec<T>::create() { data = avail = limit = 0; }
// All the elements of the vector are dropped: their destructors are called,
// and then they are removed from the vector container,
// leaving the container with a size of 0.
// The capacity remains the same, however.
template <class T>
void Vec<T>::clear()
{
std::cout << "capacity before clear: " << capacity() << std::endl;
std::cout << "data = " << data << " limit = " << limit << std::endl;
if (data) {
iterator it = avail;
// destroy objects in reverse order
while ( it != data ) {
alloc.destroy(--it);
}
}
data = avail = 0;
std::cout << "capacity after clear: " << capacity() << std::endl;
std::cout << "data = " << data << " limit = " << limit << std::endl;
}
// Controls how the vector should grow if it needs more space.
template <class T>
void Vec<T>::grow()
{
// Allocate twice as much storage as is currently used.
// If matrix is empty, allocate one element.
size_type new_size = std::max( 2*(limit-data), ptrdiff_t(1) );
// Allocate new space and copy existing elements
iterator new_data = alloc.allocate( new_size );
iterator new_avail = std::uninitialized_copy( data, avail, new_data );
// Deallocate old space
uncreate();
// Reset pointers to new values
data = new_data;
avail = new_avail;
limit = data + new_size;
}
// Create space for one element at the end and put given value there.
template <class T>
void Vec<T>::unchecked_append( const T& val )
{
alloc.construct( avail, val );
avail++;
}
Vec<int> v;
for ( int i = 0; i < 100; i++ ) {
v.push_back(i);
}
std::cout << "size=" << v.size() << " capacity=" << v.capacity() << std::endl;
v.clear();
std::cout << "size=" << v.size() << " capacity=" << v.capacity() << std::endl;
size=100 capacity=128
capacity before clear: 128
data = 0x100100280 limit = 0x100100480
capacity after clear: 1074004256
data = 0 limit = 0x100100480
size=0 capacity=1074004256