这是c++ primer书中的例题。实现了vector容器的部分功能。具体内容在第四版的18.1节。
要考虑到vector的内存分配策略。下面分别是用allocator(注释的部分)和new,delete实现的。
1.allocator
allocate(size_t t);分配原始的未构造内存以保存t个对象
deallocate(p, n);释放内存。
construct(p, t);在p所指向的内存里构造一个新元素,调用拷贝构造函数用t初始化该对象。
destroy(p);运行p所指对象的析构函数。
2.void* operator new(size_t); //分配一个对象
void* operator new[](size_t);//分配一个数组
void* operator delete(void*);//释放一个对象
void* operator delete[](void*);//释放一个数组
上面四个操作是对内存分配和释放的操作。
定位new,建立对象。
#ifndef MYVECTOR_H
#define MYVECTOR_H
#include <memory>
#include <cstddef>
using namespace std;
template <typename T>
class Vector {
public:
typedef T* iterator;
Vector():elements(0), first_free(0), end(0) {}
void push_back(const T&);
iterator begin() {return elements;}
iterator last() {return first_free;}
/*
调整vector大小,使其能容纳n个元素。
如果n小于vector当前大小,则删除多余元素。否则,添加采用值初始化的新元素
*/
void reserve(const size_t cap);
//调整vector大小,使其能容纳n个元素,所有新的元素为t
void resize(const size_t n, const T& t);
//下标操作符
T& operator[](const size_t);
const T& operator[](const size_t) const;
//返回vector大小
size_t size() {
return first_free - elements;
}
//返回vector容量
size_t capacity() {return end - elements;}
private:
//static std::allocator<T> alloc;//object to get raw memory
void reallocate();//get more space and copy existing elements
T* elements;//first element
T* first_free;
T* end;
};
//template <typename T> allocator<T> Vector<T>::alloc;
template <typename T>
void Vector<T>::push_back(const T& t) {
if(first_free == end) reallocate();
//alloc.construct(first_free, t);
new (first_free) T(t) ;
++first_free;
}
template <typename T>
void Vector<T>::reallocate() {
ptrdiff_t size = first_free - elements;
ptrdiff_t newcapcity = 2 * max(size, 1);
//T* newelements = alloc.allocate(newcapcity);
T* newelements = static_cast<T*> (operator new(newcapcity * sizeof(T)));
uninitialized_copy(elements, first_free, newelements);
//析构函数的作用:释放掉对象
//for(T* p = first_free; p != elements; ) alloc.destroy(--p);
for(T* p = first_free; p != elements; ) (--p)->~T();
//if(elements) alloc.deallocate(elements, end - elements);
if(elements) operator delete[](elements);
elements = newelements;
first_free = newelements + size;
end = elements + newcapcity;
}
template <typename T>
void Vector<T>::reserve(const size_t cap) {
size_t size = first_free - elements;
//T* newelements = alloc.allocate(cap);
T* newelements =static_cast<T*> (operator new[](cap * sizeof(T)));
if(cap >= size) uninitialized_copy(elements, first_free, newelements);
else uninitialized_copy(elements, elements+cap, newelements);
//for(T* p = first_free; p != elements;) alloc.destroy(--p);
for(T* p = first_free; p != elements;) (--p)->~T();
//if(elements) alloc.deallocate(elements, end-elements);
if(elements) operator delete[](elements);
elements = newelements;
first_free = elements + min(size, cap);
end = elements + cap;
}
template <typename T>
void Vector<T>::resize(const size_t n, const T& t) {
size_t size = first_free - elements;
size_t capacity = end - elements;
if(n > capacity) {
reallocate();
uninitialized_fill(elements+size, elements+n, t);
} else if (n > size) {
uninitialized_fill(elements+size, elements+n, t);
} else {
//for(T* p = first_free; p != elements+n;) alloc.destroy(--p);
for(T* p = first_free; p != elements+n;) (--p)->~T();
}
first_free = elements + n;
}
template <typename T>
T& Vector<T>::operator[](const size_t index) {
return elements[index];
}
#endif