vector中的成员函数总结

函数名功能
vector()构造函数
~vector()析构函数
vector(const vector& vec)拷贝构造函数
vector& operator=(const vector& vec)赋值运算符重载函数
value_type& operator[](size_t index)[]运算符重载函数(用于取出vector实例化对象的第index个元素)
bool operator==(const vector& vec)const==运算符重载函数(用于判断两个vector对象是否相等)
void push_back(value_type val)向vector示例化对象增添元素
void pop_back()删除vector实例化对象最后一个元素
void insert(iterator it,value_type val)向vector实例化对象的it位置插入一个元素
void erase(iterator it)删除vector实例化对象it位置的元素
value_type front()const取出vector对象中的第一个元素
value_type back()const取出vector对象中的最后一个元素
iterator begin()获取vector实例化对象的元素首地址
iterator end()获取vector实例化对象的最后一个元素的下一个地址
size_t size()const获取vector实例化对象的元素个数
size_t capacity()const获取vector实例化对象所占空间大小
bool empty()判断vector实例化对象是否为空

vector中的成员变量

首先为了实现vector可以实例化任意数据类型的对象,我们需要对它进行模板化,在类的定义之前增加如下语句:

template<typename T>

如我们想要实例化一个int型vector的时候,使用vector<int> vec,此时模板中的T就是指int型数据类型,那么T*就是指int*数据类型。

以下就是我们实现vector所用到的成员变量:

  • _data : 用于申请一段连续空间的指针
  • _size : 用于存放该vector对象中存放元素的个数
  • _capacity : 用于存放vector对象所申请的空间大小

该部分相关代码如下:

public:
    typedef T value_type;  // 这个并不是成员变量,主要时为了增强可读性
    typedef T* iterator;   // 其时就是重新起别名
private:
    value_type* _data;
    size_t _size;
    size_t _capacity;

我们来解释一下_capacity参数。若没有该参数,每增添一个新的元素,就需要重新申请空间存放新的元素,这会消耗较多时间,效率不高。故而在实现的时候我们采用倍增的方式提前申请较大空间,倍增的意思就是当元素个数大于空间大小时,申请的空间将会是原空间的二倍,元素个数和所申请的空间的大小对比如下:

元素个数       空间大小
   1            1
   2            2
   3            4
   4            4
   5            8

使用这种方式申请空间,当元素个数越来越多,所需申请的次数相对之前的申请方式会越来越小。

构造函数

构造函数主要用创建对象时对成员变量进行初始化

在该部分的实现涉及了初始化列表的相关知识。具体格式为在构造函数名后面使用:变量名(初始化值), ...,需要特别注意的是,初始化列表的初始化顺序并不是由构造函数后的变量顺序决定的,而是由类中成员变量的定义顺序决定的。

 vector():_data(NULL),_size(0),_capacity(0){}

析构函数

析构函数主要用于释放为实例化对象所分配的空间,当某个对象离开自己的作用域时就会自动调用析构函数,释放空间。

这里涉及一个一个知识点为,如何使用delete释放数组所占空间,必须使用delete [] 数组名来释放数组空间,单独delete 数组名只会释放数组中的第一个元素的空间。

相关代码如下:

    ~vector(){
        delete [] _data;
        _data = NULL;
        _size = 0;
        _capacity = 0;
    }

拷贝构造函数

拷贝构造函数主要功能为:用于实现vector<int> vec1 = vec2该代码功能,即实例化一个对象的时,使用另外一个对象的成员变量初始化该对象。

相关代码如下:

    vector(const vector& vec){
        _size = vec._size;
        _capacity = vec._capacity;
        _data = new value_type[_capacity];
        for(int i=0;i<_size;++i){
            _data[i] = vec._data[i];
        }
    }

如果要细究,这里其实涉及引用,const等相关知识。如果对此有疑惑,建议可以查阅相关资料。

运算符重载函数

该部分重载的运算符有:=, [] , ==。运算符重载函数的函数名格式为返回值 operator运算符(传入的参数)

我们以==运算符重载为例子,该运算符功能为判断两个对象是否相等,所以返回值为bool型,传入参数为进行比较的另外一个对象,故而函数名为bool operator==(const vector& vec)const。其中的const指的是所传入的参数是不可修改的。

赋值运算符重载函数

赋值运算符重载函数时将传入参数的所有信息拷贝一份。
针对vector而言,赋值运算符重载函数具体实现的是vec1 = ve2;,按函数调用来理解就是vec1.operator=(vec2)

具体代码如下:

    vector& operator=(const vector& vec){
        if(this == &vec) return *this;
        value_type* temp = new value_type[vec._capacity];
        for(int i=0;i<vec._size;++i){
            temp[i] = vec._data[i];
        }
        delete [] _data;
        _data = temp;
        _size = vec._size;
        _capacity = vec._capacity;
        return *this;
    }

[]运算符重载函数

针对vector而言,[]运算符重载函数具体实现的是vec[0];,按函数调用来理解就是vec.operator[](0)

具体代码如下:

    value_type& operator[](size_t index){
        return _data[index];
    }

==运算符重载函数

针对vector而言,[]运算符重载函数具体实现的是vec1 == vec2;,该判断成立成返回true,不成立返回false。按函数调用来理解就是vec1.operator==(vec2)

具体代码如下:

    bool operator==(const vector& vec)const{
        if(_size!=vec._size) return false;
        for(int i=0; i<_size; ++i){
            if(_data[i]!=vec._data[i])
                return false;
        }
        return true;
    }

增添元素

该部分分为两种。一种是默认位置增添,也就是在_data的末尾增添元素,对应实现的函数名为push_back;另一种是指定位置增添,也就是说在_data的it位置插入一个元素对应实现的函数名为insert

这两个函数的总体思路都是向一个连续空间中增添元素,我们需要将插入的位置至最后一个元素统一向后移动一个位置,从而空出一个位置用于存放新元素。在此我们也会实现倍增的方式申请空间,即_capacity *=2;,这里需要特别处理的是当原本的vec是空的时候,我们无法使用该代码来统一处理。具体如下:

push_back

相关代码如下:

    void push_back(value_type val){
        if(0==_capacity) {
            _capacity = 1;
            _data = new value_type[1];
        } else if(_size+1 > _capacity){
            _capacity *=2;
            value_type* temp = new value_type[_capacity];
            for(int i=0; i<_size; ++i){
                temp[i] = _data[i];
            }
            delete [] _data;
            _data = temp;
        }
        _data[_size] = val;
        ++_size;
    }

insert

相关代码如下:

    void insert(iterator it, value_type val){
       int index=it-_data;
       if(0==_capacity){
           _capacity = 1;
           _data = new value_type[1];
           _data[0] = val;
       }else if(_size+1 > _capacity){
           _capacity *= 2;
           value_type* temp = new value_type[_capacity];
           for(int i=0; i<index; ++i){
               temp[i] = _data[i];
           }
           temp[index] = val;
           for(int i=index; i<_size; i++){
               temp[i+1] = _data[i];
           }
           delete [] _data;
           _data = temp;
       }else{
           for(int i=_size-1; i>=index; --i){
               _data[i+1] = _data[i];
           }
           _data[index] = val;
       }
       ++_size;
    }

删除元素

删除元素分为两种方式。一种为删除末尾元素,所实现的函数名为pop_back,另一种是指定位置删除元素,所实现的函数名为erase

pop_back

    void pop_back(){
        --_size;
    }

earse

    void erase(iterator it){
       size_t index=it-_data;
       for(int i=index; i<_size-1; ++i){
           _data[i] = _data[i+1];
       }
       --_size;
    }

其他函数

其他函数功能非常简单,就不多加解释了

value_type front()const

返回vector中的第一个元素

    value_type front()const{
        return _data[0];
    }

value_type back()const

返回vector中的最后一个元素

    value_type back()const{
        return _data[_size-1];
    }

iterator begin()

返回vector中的第一个元素的地址

    iterator begin(){ return _data;}

iterator end()

返回vector中的最后一个元素的地址

    iterator end(){ return _data+_size;}

size_t size()const

返回vector中的元素个数

    size_t size()const{
        return _size;
    }

size_t capacity()const

返回vector中的所申请空间大小

    size_t capacity()const{
        return _capacity;
    }

bool empty()

判断vector是否为空

    bool empty(){
        return _size == 0;
    }

代码总结

#include <iostream>
#include <algorithm>
#include <numeric>
using namespace std;
namespace miniSTL{

template<typename T> 
class vector{
public:
    typedef T value_type;
    typedef T* iterator;
private:
    value_type* _data;
    size_t _size;
    size_t _capacity;

public:
    vector():_data(NULL),_size(0),_capacity(0){}
    ~vector(){
        delete [] _data;
        _data = NULL;
        _size = 0;
        _capacity = 0;
    }
    vector(const vector& vec){
        _size = vec._size;
        _capacity = vec._capacity;
        _data = new value_type[_capacity];
        for(int i=0;i<_size;++i){
            _data[i] = vec._data[i];
        }
    }
    vector& operator=(const vector& vec){
        if(this == &vec) return *this;
        value_type* temp = new value_type[vec._capacity];
        for(int i=0;i<vec._size;++i){
            temp[i] = vec._data[i];
        }
        delete [] _data;
        _data = temp;
        _size = vec._size;
        _capacity = vec._capacity;
        return *this;
    }
    void push_back(value_type val){
        if(0 == _capacity){
           _capacity = 1;
           _data = new value_type[1];
        }else if(_size+1 > _capacity){
           _capacity *= 2;
           value_type* temp = new value_type[_capacity];
           for(int i=0;i<_size;++i){
             temp[i] = _data[i];
           }
           delete [] _data;
           _data = temp;
        }
        _data[_size] = val;
        ++_size;
    }
    void pop_back(){ --_size;}
    size_t size()const{ return _size;}
    size_t capacity()const { return _capacity;}
    bool empty(){ return _size == 0;}
    value_type& operator[](size_t index){
        return _data[index];
    }
    bool operator==(const vector& vec)const{
        if(_size != vec._size) return false;
        for(int i=0;i<_size;++i){
            if(_data[i] != vec._data[i]) return false;
        }
        return true;
    }
    value_type front()const{ return _data[0];}
    value_type back() const{ return _data[_size-1];}
    
    void insert(iterator it,value_type val){
        int index = it - _data;
        if(0 == _capacity){
            _capacity = 1;
            _data = new value_type[1];
            _data[0] = val;
        }else if(_size+1 > _capacity){
            _capacity *= 2;
            value_type* temp = new value_type[_capacity];
            for(int i=0;i<index;++i){
                temp[i] = _data[i];
            }
            temp[index] = val;
            for(int i=index;i<_size;++i){
                temp[i+1] = _data[i];
            }
            delete [] _data;
            _data = temp;
        } else {
            for(int i=_size-1;i>=index;--i){
                _data[i+1] = _data[i];
            }
            _data[index] = val;
        }
        ++_size; 
    
    }
    void erase(iterator it){
        size_t index = it - _data;
        for(int i=index;i<_size-1;++i){
            _data[i] = _data[i+1];
        }
        --_size;
    }
    
    iterator begin(){ return _data; }
    iterator end(){ return _data + _size; }
};

}
using namespace miniSTL;
int main(){

    vector<string> vecs;
    string s;
    while(cin >> s){
       vecs.push_back(s);
    }
    
    for(auto n:vecs){
       cout << n <<" ";
    }
    cout <<endl;
}

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐