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