我正在阅读该语言作者的书《使用C ++的编程原理和实践》。
我正在阅读本书的基本部分,其中描述了如何实现std :: vector。这是本书中的一段代码:
template<typename T, typename A = std::allocator<T>> class vector {
A alloc;
int space, size;
T* elem;
//...some code
reserve(int newalloc) {
if (newalloc <= space) return; // never decrease allocation
T* p = alloc.allocate(newalloc); // allocate new space
for (int i = 0; i < sz; ++i) alloc.construct(&p[i], elem[i]); // copy
for (int i = 0; i < sz; ++i) alloc.destroy(&elem[i]); // destroy
alloc.deallocate(elem, space); // deallocate old space
elem = p;
space = newalloc;
}
};
这本书提到我们必须使用std :: allocator,因为向量的数据结构由一些初始化数据和一些未初始化数据组成。
我不清楚这意味着什么。如果我使用new和delete怎么办?
template<typename T> class vector2 {
A alloc;
int space, size;
T* elem;
//some code
reserve(int newalloc) {
if (newalloc <= space) return;
T* p = new T[newallow];
for (int i = 0; i < sz; ++i) p[i] = elem[i];
delete[] elem;
elem = p;
space = newalloc;
}
};
答案 0 :(得分:13)
如果我使用new和delete怎么办?
T* p = new T[newallow];
一个原因是,如果T
没有默认构造函数,则不会编译。
分配器的基本思想是将分配内存和对象构造的步骤分开。默认new
结合了两者。如果预留vector
,我们只想分配所需的内存。当时我们无法构造或初始化对象,因为类型可能不是默认可构造的。仅当我们将对象传递给其他操作(例如
v[i] = myObj;
如果不将内存分配和对象构造分为两个不同的步骤,就无法实现。
还请注意,当有人要自定义内存分配时,分配器具有高级用法。
这本书提到我们必须使用std :: allocator,因为向量的数据结构包含一些初始化数据和一些未初始化数据。
作者在这里的意思是,通过调用reserve
扩展容量的同时,我们将获得两种类型的数据: