我不明白 Bjarne Stroustrup - Programming Chapter 19.5.6 RAII for vector 中给出的代码:
template<typename T, typename A>
struct vector_base {
A alloc;
T* elem;
int sz;
int space;
vector_base(const A& a, int n) : alloc{a}, elem{alloc.allocate(n)}, sz{n}, space{n}{}
~vector_base() {alloc.deallocate(elem,space);}
}
//--------- vector class ------------
template<typename T, typename A = allocator<T>>
class vector : private vector_base<T,A> {
// ...
};
//--------- vector reserve ------------
template<typename T, typename A>
void vector<T,A>::reserve(int newalloc)
{
if (newalloc <= this->space) return;
vector_base<T,A> b(this->alloc,newalloc);
uninitialized_copy(b.elem, &b.elem[this->sz], this->elem);
for(int i=0; i<this->sz; ++i)
this->alloc.destroy(&this->elem[i]);
swap<vector_base<T,A>>(*this,b);
}
1) 我不明白将分配器传递给新的 vector_base
object b
需要什么。 vector_base
有自己的分配器,为什么构造函数需要 this->alloc
?
2) 我不明白 uninitialized_copy
行。看起来我们从 b
复制到 this->elem
。应该是反过来的。这只是书中的错误,还是我理解错了?
最佳答案
新的 vector
需要使用与现有 vector
相同的分配器,即 this->alloc
以确保重新分配的内存来自同一个分配区。如果使用不同的分配器,最后一行的 swap()
将交换 vector
中的内存,以指向从与稍后释放内存的分配器不同的分配器分配的内存.
std::uninitialized_copy()
的使用确实是错误的:它会从新创建的、未初始化的内存中复制到原始值。假设源和目标已正确放置,则会出现另一个错误:如果现有 vector
的内存已被完全使用,则表达式 &this->elem[this->sz]
形成对最后一个元素之后的对象的引用。该表达式应该改为 this->elem + this->sz
。也就是说,初始化应该是
uninitialized_copy(this->elem, this->elem + this->sz,
b.elem);
关于c++ - Stroustrup : C++ implementation of reserve(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51885985/