Vector的实现

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值