Vector的实现

来源:互联网 发布:java单例模式调用 编辑:程序博客网 时间:2024/05/18 17:25

C++基本数组的一些重要特性:

数组就是直线一块内存的指针变量,实际的数组的大小必须由程序员单独确定。
内存可以通过new[]来分配,但是相应地必须用delete[]来释放。
内存块的大小不能改变(但是可以定义一个新的具有更大内存块的数组,并且用原来的数组来将其初始化,然后原来的内存块就可以释放了)。

Vector类模板(避免与库函数类vector混淆)

template <typename Object>class Vectotr{  public:    explicit Vector(int initSize =0)      :theSize(initSize), theCapacity(initSize +  SPARE_CAPACITY){objects = newObject[theCapacity];}//允许使用者自己定义初始值大小(默认为0)    Vector(const Vector & rhs):objects(NULL)      {operator=(rhs);} //复制构造函数,调用Vector=对已有的Vector进行复制    ~Vector()      {delete[] objects;}    const Vector& operator= (const Vector& rhs)    {        if(this != &rhs) //检验,防止自身赋值        {            delete[] objects; //释放旧数组            theSize = rhs.size();            theCapacity = rhs.theCapacity;            objects = new Object[capacity()]; //生成与所复制的Vector同样容量的新数组            for(int k=0; k<size(); k++)                objects[k]=rhs.objects[k]; //依次复制数据项        }        return *this;    }    void resize(int newSize)    {        if(newSize > theCapacity)            reserve(newSize * 2 + 1); //对容量进行扩展,扩展为大小的两倍以避免再次扩展        theSize = newSzie; //简单设定数据成员    }    void reserve(int newCapacity)    {        if(newCapacity < theSize) //reserve函数可以用来缩小基本数组,但是所指定的新容量必须和大小一样大,否则reserve的请求就被忽略            return;         Object *oldArray = objects;         objects = new Object[newCapacity]; //分配新数组         for(int k = 0; k < theSize; k++)             objects[k] = oldArray[k]; //复制旧数组内容         theCapacity = newCapacity;         delete[] oldArray; //回收旧数组    }    Object& operator[](int index)      {return objects[index];}    const Object& operator[](int index) const      {return objects[index];} //index不在0~size()-1范围内就抛出一个异常    bool empty() const      {return size() == 0;}    int size() const      {return theSize;}    int capacity() const      {return theCapacity;}    void push_back(const Object& x)    {       if(theSize == theCapacity)         reserve(2 * theCapacity + 1);       objects[theSize++] = x; //后缀操作符,使用theSize来索引数组,然后自增theSize    }    void pop_back()      {theSize--;} //需要错误检测?    const Object& back() const      {return objects[theSize - 1];} //需要错误检测?    typedef Object* iterator;  //指针变量的别名    typedef const Object* const_iterator;    iterator begin()               //iterator和const_iterator两个begin方法和end方法的声明,指针变量可以复制和比较的特点      {return &objects[0];} //返回第一个数组位置的内存地址    const_iterator begin() const      {return &objects[0];}    iterator end()      {return &objects[size()];} //返回第一个无效的数组位置    const_iterator end() const      {return &objects[size()];}    enum{SPARE_CAPACITY = 16;};  private:    int theSize;        //数据成员,存储大小、容量    int theCapacity;    //和基本数组    Object* objects;};

文中指出,这个实现的代码中无错误检测,后面会介绍解决这个问题的策略,就是使iterator和const_iterator称为真正的嵌套类类型。

某百科中说,嵌套类型是作为某其他类型的成员的类型。嵌套类型应与其声明类型紧密关联,并且不得用作通用类型。有些开发人员会将嵌套类型弄混淆,因此嵌套类型不应是公开可见的,除非不得不这样做。在设计完善的库中,开发人员几乎不需要使用嵌套类型实例化对象或声明变量。
0 0