STL源码之实现一个简易的Vector容器
这里需要的基础知识主要是类模板和函数模板,以及一个C++内存分配的技术allocator类,它提供可感知类型的内存分配,这个类支持一个抽象接口,以分配内存并随后使用该内存保存对象。
使用allocator类,首先应用allocator类建立一个allocator对象,然后使用该对象你可以分配内存,释放内存,构造你需要的对象,释放不要的对象。
template<class T>allocator<T> Vector<T>::alloc;这句必须存在,就是生成一个allocator对象,不过在类定义时就已经实现了。没有这句在vs2010上会编译不通过,原因不清楚.
//test.h
#ifndef MYVECTOR_H
#define MYVECTOR_H
#include<memory>
#include<cstddef>
using namespace std;
template<class T>class Vector
{
public:
//默认构造函数
Vector():elements(0),first_free(0),end(0){}
void push_back(const T&);
//返回Vector的大小
size_t size()
{
return first_free-elements;
}
//返回Vector的容量
size_t capacity()
{
return end-elements;
}
private:
static std::allocator<T> alloc;//所有的Vector都用这个配置器,一个对象,用来获取原始的没有构造对象的内存
void reallocate();
T* elements;
T* first_free;
T* end;
};
template<class T>allocator<T> Vector<T>::alloc;
//往容器后面加入元素
template<class T>
void Vector<T>::push_back(const T&t)
{
//还有空间吗?
if(first_free==end)
reallocate();//没有了就重新分配
alloc.construct(first_free,t);//还有就用t构造一个新对象
++first_free;
}
template<class T> void Vector<T>::reallocate()
{
//计算当前已用空间的大小
//ptrdiff_t类型变量通常用来保存两个指针减法操作的结果,这是一种与机器无关的类型
std::ptrdiff_t size = first_free - elements;
//分配新的空间大小为原来元素个数的两倍
std::ptrdiff_t newcapacity = 2 * max(size,1);
//为容器分配新的空间,大小为newcapacity个T类型的元素,newelements指向新空间的首地址
T* newelements = alloc.allocate(newcapacity);
//把原来的元素复制到新的内存空间,把从elements开始到first_free的元素复制到从newelements开始的空间
//该函数在目的地构造元素,而不是给他们赋值,因为剩余的空间不进行初始化。
uninitialized_copy(elements,first_free,newelements);
//反序调用析构函数释放原来的内存空间里的对象
for(T *p=first_free;p!=elements;/*empty*/)
alloc.destroy(--p);
//不能释放空指针
if(elements)
alloc.deallocate(elements,end-elements);//释放原来的内存空间
//指针指向现在的空间
elements=newelements;
first_free=elements+size;
end=elements+newcapacity;
}
#endif
上面就是完整的Vector容器的建立,只提供一个功能,往容器加入元素,然后我们运行下面的函数来检查内存的占用情况,来检验我们是否正确实现了该容器。
#include"test.h"
#include<iostream>
using namespace std;
void main()
{
Vector<int> a;
cout<<"Vector已经空间: "<<a.size()<<endl;
cout<<"Vector总容量: "<<a.capacity()<<endl;
cout<<"Vector容器占用空间:"<<sizeof(a)<<endl;
}
输出结果
Vector已经空间: 0
Vector总容量: 0
Vector容器占用空间:12
请按任意键继续. . .
那么我们再让容器 添加一个元素
Vector已经空间: 1
Vector总容量: 2
Vector容器占用空间:12
请按任意键继续. . .
再让容器 添加一个元素
Vector已经空间: 2
Vector总容量: 2
Vector容器占用空间:12
请按任意键继续. . .
再让容器 添加一个元素
Vector已经空间: 3
Vector总容量: 4
Vector容器占用空间:12
请按任意键继续. . .