Stroustrup:reserve() 的 C++ 实现

Art*_*ner 8 c++

我不明白 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);
}
Run Code Online (Sandbox Code Playgroud)

1)我不明白将分配器传递给新的vector_base object b. 该vector_base有自己的分配器,为什么构造函数需要this->alloc

2)我不明白这uninitialized_copy条线。看起来我们从 复制bthis->elem。它应该是相反的。这只是书上的错误,还是我弄错了?

Die*_*ühl 6

newvector需要使用与现有的相同的分配器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);
Run Code Online (Sandbox Code Playgroud)