C++STL之vector模拟——适合像我一样新手

//author @hernoforgot

//这篇文章尽我能力的模仿了vector的实现,可以通过导入头文件的方式进行验证使用;

//这也是我第一次发表,对于许多老玩家来说我是新手,希望各位多多包涵;

/*

特点:尽可能合理命名,让多数人能够更好了解我的思路;

           尽可能注释详细,通过模拟让人更好了解vector的底层;

           代码没有经过太多优化,尽可能将它通俗;

不足: 个人觉得写得有缺漏,但是我又找不出来,希望有人能帮我看看

*/

template <class T>

class myVector{
private:
T *pBuff;
size_t maxSize;
size_t len;
public:
myVector(); //构造函数初始化
~myVector(); //析构函数
void clear(); //析构的辅助函数,方便释放内存空间
public:
myVector(int n, T const &val); //利用val这个值去生成一个大小为n的容器
myVector(int n); //利用元素的默认构造函数去生成一个大小为n的容器
myVector(myVector const& other); //拷贝构造
public:
size_t size() const; //返回当前元素的数量
bool empty() const; //返回容器是否为空
size_t capacity() const; //返回重新分配空间之前最大容器大小
void assign(int n, T const& val)const ; //复制n个val给容器
void swap(myVector &srcVector); //两个容器交换 
//如果是类成员函数,都必须对象调用;要想在模板中写非成员调用函数,就要写为友元函数
friend void swap(myVector &srcVectoro, myVector &srcVector){
//只需要交换容器的指针的指向,容器的大小和实际大小即可
T *tempBuff = srcVectoro.pBuff;
size_t tempMaxSize = srcVectoro.maxSize;
size_t tempLen = srcVectoro.len;


srcVectoro.pBuff = srcVector.pBuff;
srcVectoro.len = srcVector.len;
srcVectoro.maxSize = srcVector.maxSize;


srcVector.pBuff = tempBuff;
srcVector.len = tempLen;
srcVector.maxSize = tempMaxSize;
}


T at(int index); //返回index位置处的元素 会进行异常处理和检查
T front(); //返回第1个元素, 不检查元素是否存在
T back(); //返回最后1个元素, 不检查元素是否存在
void push_back(T const& val); //在尾部添加val
void pop_back(); //在尾部删除元素
void resize(int n); //将元素的数量改为n个,如果len<n,多出的新元素用默认构造
public:
T operator[](int index); //返回index位置处的元素,不检查元素是否存在
bool operator==(myVector const& srcVector) const;//运算符重载,两容器相等
bool operator!=(myVector const& srcVector) const;
bool operator<(myVector const& srcVector) const;
bool operator<=(myVector const& srcVector) const;
bool operator>(myVector const& srcVector) const;
bool operator>=(myVector const& srcVector) const;
bool operator=(myVector const& srcVector);


//迭代器实现部分
public:
struct myIterator//迭代器
{
T *pIt;
T operator*()
{
return *pIt;
}
//运算符重载必须满足运算符本身特点
myIterator& operator = (myIterator const& srcIt)
{
pIt = srcIt.pIt;
return *this;
}
myIterator operator + (int n)
{
myIterator it;
it.pIt = pIt;
it.pIt += n;
return it;
}
myIterator& operator++()
{
pIt++;
return *this;
}
//常量函数成员,代表自身的数据在这个函数内部不允许被修改
bool operator != (myIterator const &srcIt) const
{
return pIt != srcIt.pIt;
}
size_t operator -(myIterator const& srcIt) const
{
return pIt - srcIt.pIt;
}


};
public:
//返回末尾迭代器
myIterator end()
{
myIterator it;
it.pIt = pBuff + len;
return it;
}
//返回头迭代器
myIterator begin()
{
myIterator it;
it.pIt = pBuff;
return it;
}
public:
myIterator erase(myIterator const&first, myIterator const& last);//作业
myIterator erase(myIterator const& pos)//删除pos位置的值,返回新的位置
{
//注意,在比较小的位置系统的删除可能也会导致迭代器失效,无法模拟
int index = pos.pIt - pBuff;
for (int i = index; i < len; ++i)
{
pBuff[i] = pBuff[i + 1];
}
len--;
MyIterator tempIt;
tempIt.pIt = pBuff + index;
return tempIt;
}
void insert(myIterator const&pos, myIterator const&first, myIterator const& last);
//在pos位置上插入val,并返回新的插入元素的位置
myIterator insert(myIterator const& pos, T const& val)
{
int index = pos.pIt - pBuff;
if (len >= maxSize)//如果当前个数和最大大小相同,证明没有空间存放数据
{
maxSize = maxSize + ((maxSize >> 1) > 1 ? (maxSize >> 1) : 1);
T *tempBuff = new T[maxSize];
memcpy(tempBuff, pBuff, sizeof(T)* len);
if (pBuff)
delete[]pBuff;
pBuff = tempBuff;
}
for (int i = len - 1; i >= index; --i)
{
pBuff[i + 1] = pBuff[i];
}
pBuff[index] = val;
len++;
myIterator it;
it.pIt = pBuff + index;
return it;
}
myVector(myIterator fisrt, myIterator second);
};
//初始部分的模拟操作 及优化
template <class T>
void myVector<T>::clear(){
if (pBuff)     //即 pBuff != NULL
delete[] pBuff;
len = maxSize = 0;
}
template <class T>
myVector<T>::myVector(){
pBuff = NULL;
len = 0;
maxSize = 0;
}
template <class T>
myVector<T>::~myVector(){
clear();
}
//附加的重载构造函数 定义
template <class T>
myVector<T>::myVector(int n, T const &val){
len = maxSize = n;
pBuff = new T[maxSize];
for (int i = 0; i < n; ++i){
pBuff[i] = val;
}
}
template <class T>
myVector<T>::myVector(int n){
len = maxSize = n;
pBuff = new T[maxSize];
}
template <class T>
myVector<T>::myVector(myVector const& other){
len = other.len;
maxSiez = other.maxSize;
pBuff = NULL;
if (other.pBuff != NULL)
{
pBuff = new T[maxSize];
memcpy(pBuff, other.pBuff, sizeof(T)* len);   //将值赋给pBuff指针
}
}
//重载函数 对整个容器宏观操作
template <class T>
size_t myVector<T>::size()const{
return len;
}
template <class T>
bool myVector<T>::empty() const{
return len == 0;
}
template <class T>
size_t myVector<T>::capacity() const{
return  maxSize;
}
template <class T>
void myVector<T>::assign(int n, T const &val) const{
//先释放内存,再进行复制  使用后与重载的构造方法相似
clear();
len = maxSize = n;
pBuff = new T[maxSize];
for (int i = 0; i < n; ++i){
pBuff[i] = val;
}
}
template <class T>
void myVector<T>::swap(myVector & srcVector){
//只需要交换容器的指针的指向,容器的大小和实际大小即可
T *tempBuff=pBuff;   //此处需要一个临时的T类型的指针 用来改变指向
size_t tempMaxSize = maxSize;
size_t tempLen = len;


pBuff = srcVector.pBuff;
len = srcVector.len;
maxSize = srcVector.maxSize;
srcVector.pBuff = tempBuff;
srcVector.len = tempLen;
srcVector.maxSize = tempMaxSize;
}
//对容器内部的细节操作函数  
template <class T>
T myVector<T>::at(int index){
if (index < 0 || index >= len) //注意是>=len 不是> 想做是下标的数组
throw"rang_out";                //提示越界  at是为数不多的异常检查函数
return pBuff[index]; //返回对应下标元素
}
template <class T>
T myVector<T>::front(){
return pBuff[0];
}
template <class T>
T myVector<T>::back(){
return pBuff[len-1];               //注意越界问题  len与数组下标的关系
}
template <class T>
void myVector<T>::pop_back(){
len--; //是len-- 而不是maxSize-- 注意两者的区别
}
template <class T>
void myVector<T>::push_back(T const& val){
//因为需要在尾部添加 故要判断原容器是否满,满了就需要重新分配内存
if (len >= maxSize){
//申请新内存的大小规律  本身+本身/2  
maxSize = maxSize + ((maxSize >> 1) > 1 ? (maxSize >> 1) : 1);
T *tempBuff = new T[maxSize];
    //将之前的容器元素赋值过来
memcpy(tempBuff, pBuff, sizeof(T)*len);  
//释放原内存
if (pBuff) delete[]pBuff;
//改变pBuff指针指向,指向新的容器
pBuff = tempBuff;
}
//最后添加元素
pBuff[len++] = val;
}
template <class T>
void myVector<T>::resize(int n){
if (n >= maxSize)
//与上方插入相似 重新申请内存   PS:此处可以把重新申请内存写成函数 从而优化
{
maxSize = n;
T *tempBuff = new T[maxSize];
memcpy(tempBuff, pBuff, sizeof(T)* len);
if (pBuff)
delete[]pBuff;
pBuff = tempBuff;
}
len = n;
}
// 运算符的重载
template <class T>
T myVector<T>::operator[](int index){
return pBuff[index];
}
template <class T>
bool myVector<T>::operator==(myVector const &srcVector)const{
//第一步判断 两个容器元素个数是否相等
if (len == srcVector.len){
//第二步判断 两个容器内是否所有元素相等
for (int i = 0; i < len; ++i){
if (pBuff[i] != srcVector.pBuff[i]) return false;
}
return true;
}
else
return false;
}
template <class T>
bool myVector<T>::operator!=(myVector const &srcVector)const{
return !(*this == srcVector);     //*this 表示对象 this表示指针
}
template <class T>
bool myVector<T>::operator<(myVector const &srcVector)const{
//首先进行空容器的判断
if (len == 0 || srcVector.len == 0){
if ((len == 0 && srcVector.len != 0)) return true;
else return false;
}
//然后考虑两个容器都有元素的情况
else{
int tempLen = (len < srcVector.len) ? len : srcVector.len;
for (int i = 0; i < tempLen; ++i)
{
if (pBuff[i] < srcVector.pBuff[i])
return true;
if (pBuff[i] > srcVector.pBuff[i])
return false;
}
请特别注意 此处的返回值
请特别注意 此处的返回值
if (len<srcVector.len)
return true;
else
return false;
}
}
template <class T>
bool myVector<T>::operator>(myVector const &srcVector)const{
//可以稍微偷一下懒,从<运算符中进行改动即可


//同样的  首先进行空容器的判断
if (len == 0 || srcVector.len == 0){
if ((len != 0 && srcVector.len == 0)) return true;
else return false;
}
//然后考虑两个容器都有元素的情况
else{
int tempLen = (len < srcVector.len) ? len : srcVector.len;
for (int i = 0; i < tempLen; ++i)
{
if (pBuff[i] > srcVector.pBuff[i])
return true;
if (pBuff[i] < srcVector.pBuff[i])
return false;
}
请特别注意 此处的返回值
请特别注意 此处的返回值
if (len>srcVector.len)
return true;
else return false;
}
}
template <class T>
bool myVector<T>::operator>=(myVector const &srcVector)const{
return (*this>srcVector || *this == srcVector);
}
template <class T>
bool myVector<T>::operator<=(myVector const &srcVector)const{
return (*this<srcVector || *this == srcVector);
}
template <class T>
myVector<T>::myVector(myIterator fisrt, myIterator second)
{
len = maxSize = 0;
pBuff = NULL;
int n = 0;
if ((n = second - fisrt) > 0)
{
maxSize = len = n;
pBuff = new T[n];
for (int i = 0; i < n; ++i)
pBuff[i] = *(fisrt + i);
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值