vector第四步修炼之道

在使用系统中自带的STL库时,我们会使用迭代器来访问容器中的元素。那么《vector第二步修炼之道》和《vector第三步修炼之道》之中,我们均是使用自定义vector 类的show() 函数来进行访问的。当然,我们也是可以自定义迭代器来实现元素的访问。

准备资料:

首先,看如下的代码:

void show(vector<int>& vec)
{
    vector<int>::iterator it = vec.begin();
    for (; it != vec.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

我们可以看到模板类vector,其中迭代器在模板类中的作用域内,那么我们可以做下面几件事:
(1)自定义迭代器作为模板类的内置类,并定义构造函数;
(2)需要重载的运算符:!=,前置++,*;
(3)需要定义模板类的begin() 和end() 方法

代码书写:

#pragma once
#include<iostream>
using namespace std;

template<typename T>
class myAllocator
{
public:
    //allocate   : 开辟内存的    malloc    ptmalloc  
    T* allocate(size_t size)
    {
        return (T*)operator new(sizeof(T)*size);
    }
    //deallocate : 释放内存的    free
    void deallocate(void  *p)
    {
        operator delete(p);
    }
    void construct(T* _P, const T& _V)
    {
        new (_P) T(_V);
    }
    //destroy : 专门析构的
    void destroy(T* _P)
    {
        _P->~T();
    }

};


template <typename E, typename A = myAllocator<E>>
class vector
{
public:
    //默认构造函数,所有成员都给默认的零值
    vector(int initialsize = 0, const A &a = A());
    //vector(int initialsize , const A &a );
    //num:初始元素的个数,value表示初始元素的值
    vector(int num, E value);
    //用[first, last)区间的元素初始化当前容器
    vector(E *first, E *last);
    //析构函数
    ~vector();
    //拷贝构造函数
    vector(const vector&src);
    //赋值运算符的重载函数
    void operator=(const vector&src);
    //向容器的末尾添加新元素value,若增长内存,调用resize函数
    void push_back(const E &value);
    //删除容器末尾的元素
    void pop_back();
    //查找某个元素的地址
    E* getpos(int val);
    //向指定位置pos插入新元素value,若增长内存,调用resize函数
    void insert(E *pos, const E &value);

    //删除指定位置的元素
    void erase(E *pos);
    //打印容器有效元素值的函数
    void show()const;
    //判断容器是否空
    bool empty()const;
    //判断容器是否满
    bool full()const;
    //获取容器元素个数
    int size() const;
//自定义迭代器类
    class Iterator
    {
    public:
        Iterator(E *ptr = NULL)
            :ptr(ptr) {}
        //访问元素
        E& operator*()
        {
            return *ptr;
        }
        E& operator[](int index)
        {
            return ptr[index];
        }
        //重载运算符前置++
        void operator++()    //void 类型,无引用
        {
            ++ptr;
        }
        //重载运算符前置!=
        bool operator!=(const Iterator &iter)
        {
            return ptr != iter.ptr;
        }
        //重载运算符前置-
        int operator-(const Iterator &iter)
        {
            return ptr - iter.ptr;
        }
    private:
        E *ptr;
    };
    //获取容器首元素地址
    Iterator begin()
    {
        return Iterator(_first);
    }
    //获取容器末尾元素地址
    Iterator end()
    {
        return Iterator(_first+_last);
    }
private:
    //内存增长函数,按原有容量的两倍增长
    void resize()
    {
        if (_end == 0)//默认构造vector;
        {
            _end = 1;
            _first = _allocator.allocate(_end);

        }
        else
        {
            E *_newfirst = _allocator.allocate(_end * 2);
            for (int i = 0; i < _end; i++)
            {
                _allocator.construct(_newfirst + i, _first[i]);
                _allocator.destroy(_first + i);
            }
            _end *= 2;
            _allocator.deallocate(_first);
            _first = _newfirst;
        }
    }
    A _allocator;//存储用户指定的空间配置器
    E *_first;   //存储放入容器的元素
    int _end;      //_element数组的总容量
    int _last;     //_element有效元素的个数
};
//默认构造函数,所有成员都给默认的零值
template <typename E, typename A = myAllocator<E>>
vector<E, A>::vector(int initialsize = 0, const A &a = A())
    :_last(0), _end(initialsize), _allocator(a)
{
    if (initialsize == 0)
    {
        _first = NULL;
    }
    else
    {
        _first = _allocator.allocate(_end);
    }
}
//num:初始元素的个数,value表示初始元素的值
template <typename E, typename A = myAllocator<E>>
vector<E, A>::vector(int num, E value)
    :_end(num), _last(num)
{
    _first = _allocator.allocate(num);
    for (int i = 0; i < _end; i++)
    {
        _allocator.construct(_first + i, value);
    }
}
//
//用[first, last)区间的元素初始化当前容器
template <typename E, typename A = myAllocator<E>>
vector<E, A>::vector(E *first, E *last)
{
    int size = *last - *first;
    _first = _allocator.allocate(size);
    _end = _last = size;
    for (int i = 0; i < size; i++)
    {
        _allocator.construct(_first + i, (*first)++);
    }
}
//析构函数
template <typename E, typename A = myAllocator<E>>
vector<E, A>::~vector()
{
    if (_first != NULL)
    {
        for (int i = 0; i < _last; i++)
        {
            _allocator.destroy(_first + i);
        }
        _allocator.deallocate(_first);
        _first = NULL;
        _end = 0;
        _last = 0;
    }
}
//拷贝构造函数
template <typename E, typename A = myAllocator<E>>
vector<E, A>::vector(const vector &src)
{
    _end = src._end;
    //_first = new E[_end];
    _first = _allocator.allocate(_end);
    _last = src._last;
    for (int i = 0; i < _last; i++)
    {
        _allocator.construct(_first + i, (src._first)[i]);
    }
}
//赋值运算符的重载函数
template <typename E, typename A = myAllocator<E>>
void vector<E, A>::operator=(const vector &src)
{
    if (this == &src)
    {
        return;
    }

    if (_first != NULL)
    {
        for (int i = 0; i < _last; i++)
        {
            _allocator.destroy(_first + i);
        }
        _allocator.deallocate(_first);
    }

    _end = src._end;
    _first = _allocator.allocate(_end);
    _last = src._last;
    for (int i = 0; i < _last; i++)
    {
        _allocator.construct(_first + i, (src._first)[i]);
    }
}
//向容器的末尾添加新元素value,若增长内存,调用resize函数
template <typename E, typename A = myAllocator<E>>
void vector<E, A>::push_back(const E &value)
{
    if (full())
    {
        resize();
    }
    _allocator.construct(_first + _last, value);
    _last++;
}
//删除容器末尾的元素
template <typename E, typename A = myAllocator<E>>
void vector<E, A>::pop_back()
{
    if (!empty())
    {
        _last--;
        _allocator.destroy(_first + _last);
    }
}
// vector 元素的位置
template <typename E, typename A = myAllocator<E>>
E* vector<E, A>::getpos(int val)
{
    for (int i = 0; i < _end; i++)
    {
        if (_first[i] == val)
        {
            return &(_first[i]);
        }
    }
    return NULL;
}

//向指定位置pos插入新元素value,若增长内存,调用resize函数
template <typename E, typename A = myAllocator<E>>
void vector<E, A>::insert(E *pos, const E &value)
{
    int index = pos - _first;
    if (index<0 || index>_last)
    {
        printf("error");
        return;
    }
    if (full())
    {
        resize();
    }
    if (index < _last)
    {
        for (int i = _last; i > index; --i)
        {
            _allocator.construct(_first + i, _first[i - 1]);
            _allocator.destroy(_first + i - 1);
        }
    }
    _allocator.destroy(_first + index);
    _allocator.construct(_first + index, value);
    _last++;
}

//删除指定位置的元素
template <typename E, typename A = myAllocator<E>>
void vector<E, A>::erase(E *pos)
{
    int index = pos - _first;
    if (index<0 || index>_last)
    {
        printf("error");
        return;
    }
    if (!empty())
    {
        for (int i = index; i < _last - 1; i++)
        {
            _allocator.destroy(_first + i);
            _allocator.construct(_first + i, _first[i + 1]);
        }
        _last--;
        _allocator.destroy(_first + _last);
    }
}
//打印容器有效元素值的函数
template <typename E, typename A = myAllocator<E>>
void vector<E, A>::show()const
{
    if (_first != NULL)
    {
        for (int i = 0; i < _last; i++)
        {
            cout << _first[i];
        }
        cout << endl;
    }
}
//判断容器是否空
template <typename E, typename A = myAllocator<E>>
bool vector<E, A>::empty()const
{
    if (_last == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}
//判断容器是否满
template <typename E, typename A = myAllocator<E>>
bool vector<E, A>::full()const
{
    if (_last == _end)
    {
        return true;
    }
    else
    {
        return false;
    }
}
//获取容器元素
template <typename E, typename A = myAllocator<E>>
int vector<E, A>::size()const
{
    return _last;
}

测试函数

#include<iostream>
//#include "vectorAllocate.h"
#include "vectorAllocateIterator.h"
using namespace std;


int main()
{
    /*******vectorAllocateIterator的使用********/
    myAllocator<int> alloc;
    vector<int, myAllocator<int>> vec1(10, alloc);
    vec1.show();
    vector<int, myAllocator<int>> vec2(10, 1);
    vec2.show();
    vector<int>::Iterator iter = vec2.begin();
    for (; iter != vec2.end(); ++iter)
    {
        cout << *iter << " ";
    }
    cout << endl;
    vector<int>::Iterator iter2 = vec2.begin();  //此时iter已经指向容器最后一个元素了,故需要重新定义
    for (int i = 0; i < vec2.size(); i++)
    {
        cout << iter2[i] << " ";
    }
    cout << endl;

    return 0;
}

其中还有个问题我还没弄清楚,搞清楚后一定补上。

猜你喜欢

转载自blog.csdn.net/u013266600/article/details/78816669