Stroustrup:reserve()的C ++实现

时间:2018-08-16 22:11:46

标签: c++

我不明白Bjarne Stroustrup-为矢量编程的19.5.6 RAII章节中给出的代码

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对象b的需要。 vector_base有其自己的分配器,为什么构造函数需要“ this-> alloc”

2)我不了解uninitialized_copy行。好像我们从b复制到this-> elem。反之亦然。这只是书中的错误,还是我弄错了?     }

1 个答案:

答案 0 :(得分:1)

新的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);