码迷,mamicode.com
首页 > 其他好文 > 详细

关于allocator的一些基础用法以及简易的vector实现

时间:2014-09-24 00:27:55      阅读:284      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   os   使用   ar   for   

首先,关于allocator戳旁边→维基百科-分配器(C++)

这次我只用了其中的一部分API,来实现一个简易的vector容器,这个简易版vector实现了插入、删除、查找等简易功能,由于对右值的理解不足,所以这次并未实现关于右值的API。

MSDN-class allocator_base API

此次用到的有:

  • allocate - 用于分配、再分配空间
  • construct - 用于构造对象
  • destroy - 用于销毁对象(调用其构造函数)

 接下来开始,用例子一点点的说明如何使用allocator来编写一个vector类。

完整的源码在最下面可以下载。


首先,先给出一些typedef

typedef T           value_type;
typedef T*          pointer;
typedef const T*    const_pointer;
typedef T*          iterator;
typedef const T*    const_iterator;
typedef T&          reference;
typedef const T&    const_reference;
typedef size_t      size_type;
typedef ptrdiff_t   different_type;

其中T为typename,此处还用了指向T的指针来实现迭代器的用途。在使用typedef后,可更方便的理解代码,增强可读性。


 关于这个Vector类中的allocator,我选择了包含而非私有继承的方式,个人感觉这样的代码可读性更高,更易于修改维护。

类的私有部分,有如下四个成员:

//存储区
std::allocator<value_type> _alloc_vec;
//指向首位的指针
pointer _first;
//指向末位的指针
pointer _last;
//记录当前容量
size_type _capacity;

allocator用来分配内存,存储元素;两个T*类型的指针分别指向Vector的开始以及结尾;size_type类型的_capacity则用来记录Vector的当前容量,在容量不足时就扩充。


 然后是成员函数,成员函数我是根据MSDN上提供的来编写的,所以全是公有成员函数,但是也足够完成这个简易的类了。

首先,构造函数、复制构造函数、析构函数以及重载的‘=‘符号

//默认构造函数
Vector(size_type _size = 256) :
  _first(_alloc_vec.allocate(_size)),
  _last(_first),
  _capacity(_size) { }
//复制构造函数 Vector(const Vector& Right) :   _first(_alloc_vec.allocate(Right._capacity)),   _last(_first),
  _capacity(Right._capacity)
{
  for (auto p : Right)     _alloc_vec.construct(_last++, p); } //默认析构函数 ~Vector() = default; //重载‘=‘ Vector& operator=(const Vector<T>& Right) {   return Vector(Right); }

默认构造函数用了一个默认大小为256的_size参数来初始化对象,预分配一个不算太小的内存空间,也方便将来扩充。

_first(_alloc_vec.allocate(_size))

这一句的作用,等同于

_first = _alloc_vec.allocate(_size);

即给_alloc_vec分配一个大小为_size的空间,并且将_first指向其首位。具体函数声明请戳MSDN。

之后,由于没有给对象中添加元素,所以_last与_first指向相同的地址,即_alloc_vec的首位,然后将_size的值存入_capacity。

关于拷贝构造函数,先是用capacity()函数来获取Right的容量,然后让调用对象分配一个相同大小的空间,并且将两个指针都指向其首位,然后记录容器大小,接着进入函数体,用for循环将Right中的元素都拷贝至调用对象中,并且修改_last指向的位置。

注意,无论是何种构造函数,_last指向的位置都是最后一个元素的下一位。

至于析构函数则直接使用默认析构函数,而等号就直接调用复制构造函数。(才不是因为偷懒


 然后是pop_back()以及push_back()这两个较容易实现的成员函数。

//删除末尾元素
void pop_back()
{
    _alloc_vec.destroy(--_last);
}

//将元素插入末位
void push_back(reference val)
{
    if (size() >= _capacity)
    {
        _alloc_vec.allocate(_capacity);
        _capacity *= 2;
    }

    _alloc_vec.construct(_last++, val);
}

pop_back()中调用了destroy函数,这个函数将会调用自减1之后的_last指针所指向的对象的析构函数,销毁该对象,而这一动作完成后,_last仍旧指向最后一位元素的下一位。

push_back()在将元素加入Vector之前,会检查容量是否足够分配空间,若是不够,则调用allocate来分配更多的空间;将元素加入,调用了construct,这个函数将调用类型为T的构造函数,并且在将其加入之后,将_last后移一位。


 然后好像那三个函数就介绍完了……剩下的Vector中的insert和erase函数也就是运用了与push_back以及pop_back类似的方法……所以就不写了。(嗬嗬嗬

至于其他的都是一些对指针的操作……嗯就这样吧……(逃

完整源码下载

关于allocator的一些基础用法以及简易的vector实现

标签:des   style   blog   http   color   os   使用   ar   for   

原文地址:http://www.cnblogs.com/LzxHehehe/p/3989569.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!