用到数组就会想到对应的可以动态增加空间的向量vector
下面是模拟STL的基本功能,参《C++ Primer》第四版
将实现文件也写到类中的,可以无视代码风格
这里用到了内存管理的类 allocator
allocator
a.allocate(n) 分配原始的T类型的n个对象,不会调用T的构造函数
a.deallocate(p,n) 释放内存,首地址为p,的n个T类型的对象
a.construct(p,t) p为T*类型,p所指的地址处构造新元素,调用T的复制构造函数用t初始化该对象
a.destroy(p) 与上面相对应,p所指的对象处调用析构函数
uninitialized_copy(b,e,b2) 从b到e的元素,复制给b2所指的内存
uninitialized_fill(b,e,t) 从b到e范围中的对象,初始化为t
uninitialized_fill(b,e,t,n) 从b到e范围中的对象,n个初始化为t
这里的内存分配是按照先前分配的2倍
STL中的是按照加上原来的一半的分配策虐
template
class Vector
{
public:
Vector() :element(NULL), first_free(NULL), end(NULL) {}
// operation
public:
void pop_back() // pop_back()
{
alloc.destroy(--first_free);
}
void push_back(const T& t) // push_back()
{
if (first_free == end)
reallocate();
alloc.construct(first_free, t);
first_free++;
}
T* erase(T *p) // erase()
{
copy(p + 1, first_free, p);
alloc.destroy(--first_free);
return p;
}
T& front() // front()
{
return *element;
}
T& back() // back()
{
return *(--fist_free);
}
void resize(size_t n) // they should be initialized (standard library)
{
size_t size = first_free - element;
size_t capability = end - element;
if (n > capability){
reallocate();
uninitialized_fill(element + size, element + n, T());
}
else if (n > size){
uninitialized_fill(element + size, element + n, T());
}
else
for (T *p = first_free; p != element + n;)
alloc.destroy(--p);
fist_free = element + n;
}
void resize(size_t n, T& t)
{
size_t size = first_free - element;
size_t capability = end - element;
if (n > capability){
reallocate();
uninitialized_fill(element + size, element + n, t);
}
else if (n > size){
uninitialized_fill(element + size, element + n, t);
}
else
for (T *p = first_free; p != element + n;)
alloc.destroy(--p);
fist_free = element + n;
}
void reserve(const size_t capa) // 设置储备空间 capability
{
size_t size = first_free - element;
T *newelement = alloc.allocate(capa); // 分配的连续的空间
if (size <= capa)
uninitialized_copy(element, first_free, newelement);
else
uninitialized_copy(element, element + capa, newelement);
for (T *p = fist_free; p != element;)
alloc.destroy(--p);
if (element)
alloc.deallocate(element, end - element);
element = newelement;
if (size <= capa) first_free = element + size;
else first_free = element + capa;
end = element + capa;
}
T& operator[](size_t index)
{
return element[index];
}
const T& operator[](size_t index) const
{
return element[index];
}
size_t capability()
{
return end - element;
}
size_t size()
{
return first_free - element;
}
T* _begin()
{
return this->element;
}
T* _end()
{
return this->end;
}
private:
static std::allocator alloc;
void reallocate()
{
std::ptrdiff_t size = first_free - element;
std::ptrdiff_t newsize = 2 * __max(size, 1); // 分配原来的两倍
T *newelement = alloc.allocate(newsize);
uninitialized_copy(element, first_free, newelement);
for (T *p = first_free; p != element;)
alloc.destroy(--p); // 这是调用析构
if (element)
alloc.deallocate(element, end - element); // 释放内存
element = newelement;
first_free = element + size;
end = element + newsize;
}
T* element;
T* first_free;
T* end;
};
template
std::allocator Vector::alloc;