Chinaunix首页 | 论坛 | 博客
  • 博客访问: 45650
  • 博文数量: 15
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 176
  • 用 户 组: 普通用户
  • 注册时间: 2014-01-31 01:57
个人简介

资深码农

文章分类

全部博文(15)

文章存档

2016年(3)

2014年(12)

我的朋友

分类: C/C++

2014-03-14 16:03:05

STL是C++的精髓,其中的vector又是用的最广的一种容器。下面介绍一下vector的一种简单实现(这里参考了Mark Weiss的数据结构C++实现一书),废话不多说,直接上代码,

点击(此处)折叠或打开

  1. #include "stdafx.h"
  2. #include <iostream>
  3. #include <string>

  4. using namespace std;

  5. template <typename Object>
  6. class Vector
  7. {
  8. public:
  9.     explicit Vector(int initSize = 0) : theSize(initSize), theCapacity(initSize+SPARE_CAPACITY)
  10.     {
  11.         objects = new Object[theCapacity];
  12.     }
  13.     Vector(const Vector & rhs) : objects(NULL)
  14.     {
  15.         operator=(rhs);
  16.     }
  17.     ~Vector()
  18.     {
  19.         delete [] objects;
  20.     }

  21.     const Vector & operator=(const Vector & rhs)
  22.     {
  23.         if (this != &rhs)
  24.         {
  25.             delete [] objects;
  26.             theSize = rhs.size();
  27.             theCapacity = rhs.theCapacity;

  28.             objects = new Object[capacity()];
  29.             for (int k = 0; k < size(); k++)
  30.                 objects[k] = rhs.objects[k];
  31.         }
  32.         return *this;
  33.     }
  34.     void resize(int newSize)
  35.     {
  36.         if (newSize > theCapacity)
  37.             reserve(newSize*2+1);
  38.         theSize = newSize;
  39.     }
  40.     void reserve(int newCapacity)
  41.     {
  42.         if (newCapacity < theCapacity)
  43.             return;

  44.         Object * oldArray = objects;
  45.         objects = new Object[newCapacity];
  46.         for (int k = 0; k < theSize; k++)
  47.             objects[k] = oldArray[k];

  48.         theCapacity = newCapacity;
  49.         delete [] oldArray;
  50.     }

  51.     Object * operator[](int index)
  52.     {
  53.         return objects[index];
  54.     }
  55.     const Object & operator[](int index) const
  56.     {
  57.         return objects[index];
  58.     }
  59.     bool empty() const
  60.     {
  61.         return size() == 0;
  62.     }
  63.     int size() const
  64.     {
  65.         return theSize;
  66.     }
  67.     int capacity() const
  68.     {
  69.         return theCapacity;
  70.     }

  71.     void push_back(const Object & x)
  72.     {
  73.         if (theSize == theCapacity)
  74.             reserve(2*theCapacity+1);
  75.         objects[theSize++] = x;
  76.     }

  77.     void pop_back()
  78.     {
  79.         theSize--;
  80.     }

  81.     const Object & back() const
  82.     {
  83.         return objects[theSize-1];
  84.     }

  85.     typedef Object * iterator;
  86.     typedef const Object * const_iterator;

  87.     iterator begin()
  88.     {
  89.         return &objects[0];
  90.     }

  91.     const_iterator begin() const
  92.     {
  93.         return &objects[0];
  94.     }

  95.     iterator end()
  96.     {
  97.         return &objects[theSize];
  98.     }

  99.     const_iterator end() const
  100.     {
  101.         return &objects[theSize];
  102.     }

  103.     enum
  104.     {
  105.         SPARE_CAPACITY = 16
  106.     };

  107. private:
  108.     int theSize;
  109.     int theCapacity;
  110.     Object * objects;
  111. };

  112. int _tmain(int argc, _TCHAR* argv[])
  113. {
  114.     Vector<string> aVec;
  115.     aVec.push_back("hello");
  116.     aVec.push_back("my name is Lily");
  117.     aVec.push_back("I hope we'll be friends");
  118.     aVec.push_back("Thanks");
  119.     Vector<string>::iterator iter = aVec.begin();
  120.     while (iter != aVec.end())
  121.         cout << *iter++ << endl;
  122.     return 0;
  123. }

先从vector的private成员变量说起,定义theSize,即size()的返回值,该值表明了vector的size大小;theCapacity,即vector的容量,注意它与size不是一个概念,size是指一个容器里面装了多少元素,capacity指该容器目前占用的内存能容纳多少元素,但未必里面就有那么多元素,可能capacity非常大,但size很小;objects指针里面存放的是vector分配内存的地址。当定义一个空的vector时,capacity是多少?在这里是16,请见code的120行定义的SPARE_CAPACITY,以及11行的构造函数,当未指定initSize的时候,我们new一个SPARE_CAPACITY的数组,用来存放Object对象。
下一个需要关注的函数是第44行的reserve(),reserve就是指定vector去分配一个指定大小的内存,当然如果这个指定的大小小于当前vector的capacity,那我们就什么都不做,如果大于当前capacity,我们先new一个new capacity的内存,然后把vector当前保存的元素拷贝到新new的内存中,最后删除之前分配的内存(注意删除数组要用delete [] p的形式,否则会发生内存泄漏)。
接下来我们来看一下迭代器的定义,我们这里把iterator直接定义为指向Object的指针,然后再定义begin(), end()等函数,这几个函数都很简单,直接返回&objects[x]即可。
最后我们看代码79行push_back的定义,这个函数是vector使用者用的最多的操作之一,实现push_back时要考虑vector容量是否已满的情况,如果容量已满,即theSize与theCapacity相等,则reserve一个2倍的capacity加1即可。在这里理论上只要reserve的容量大于当前capacity,那reserve多大的内存都可以,但是如果reserve的内存过小(比如每次只增加一个Object大小的内存,那么以后每次push_back操作都会引起reserve操作,而reserve操作是要涉及new delete动作的,频繁进行会非常耗时),所以一般每次容量已满的话都reserve一个2倍的当前capacity的大小是理想的方法。
测试程序非常简单,定义一个装string对象的vector,然后进行push_back,最后打印出来,显示如下,


点击(此处)折叠或打开

  1. hello
  2. my name is Lily
  3. I hope we'll be friends
  4. Thanks

写一个vector对理解C++ STL绝对是非常有帮助的,看似简单的一个vector实际上里面涉及了C++的模板,重载等概念,对于一个C++的新手来说,能写对这些语法并且通过编译就不是一件容易的事,所以学习软件编程最好的方法还是写一些实实在在的程序,大有裨益。




阅读(3345) | 评论(0) | 转发(0) |
0

上一篇:C++字符串匹配算法

下一篇:STL的list实现

给主人留下些什么吧!~~