Vector的一种实现(二)

 

增加了逆置迭代器的实现

以及swap功能

 

完整代码如下:

#ifndef VECTOR_H_
#define VECTOR_H_

#include <stddef.h>
#include <algorithm>
#include <memory>

template <typename T>
class Vector
{
public:
    typedef T *iterator;
    typedef const T *const_iterator;
    typedef size_t size_type;
    typedef T value_type;

    //逆置迭代器
    class reverse_iterator
    {
    public:
        reverse_iterator(iterator it = NULL) :current_(it) { }
        iterator base() const { return current_; }

        reverse_iterator &operator++()
        {
            --current_;
            return *this;
        }
        reverse_iterator operator++(int)
        {
            reverse_iterator temp(*this);
            --current_;
            return temp;
        }
        reverse_iterator &operator--()
        {
            ++current_;
            return *this;
        }
        reverse_iterator operator--(int)
        {
            reverse_iterator temp(*this);
            ++current_;
            return temp;
        }

        T &operator*()
        {
            iterator temp = current_;
            return *--temp;
        }

        T *operator->()
        {
            iterator temp = current_;
            return --temp;
        }

        friend bool operator==(const reverse_iterator &lhs, const reverse_iterator &rhs)
        {
            return lhs.current_ == rhs.current_;
        }

        friend bool operator!=(const reverse_iterator &lhs, const reverse_iterator &rhs)
        {
            return lhs.current_ != rhs.current_;
        }

    private:
        iterator current_;
    };

    //const逆置迭代器
    class const_reverse_iterator
    {
    public:
        const_reverse_iterator(const_iterator it = NULL) :current_(it) { }
        const_iterator base() const { return current_; }

        const_reverse_iterator &operator++()
        {
            --current_;
            return *this;
        }
        const_reverse_iterator operator++(int)
        {
            const_iterator temp(*this);
            --current_;
            return temp;
        }
        const_reverse_iterator &operator--()
        {
            ++current_;
            return *this;
        }
        const_reverse_iterator operator--(int)
        {
            const_iterator temp(*this);
            ++current_;
            return temp;
        }

        const T &operator*() const
        {
            const_iterator temp = current_;
            return *(--temp);
        }

        const T *operator->() const
        {
            const_iterator temp = current_;
            return --temp;
        }

        friend bool operator==(const const_reverse_iterator &lhs, const const_reverse_iterator &rhs)
        {
            return lhs.current_ == rhs.current_;
        }

        friend bool operator!=(const const_reverse_iterator &lhs, const const_reverse_iterator &rhs)
        {
            return lhs.current_ != rhs.current_;
        }

    private:
        const_iterator current_;
    };

    Vector() { create(); }
    explicit Vector(size_type n, const T &t = T())  { create(n, t); }
    Vector(const Vector &v) { create(v.begin(),  v.end()); }
    ~Vector() { uncreate(); }

    Vector &operator=(const Vector &other);
    T &operator[] (size_type i) { return data_[i]; }
    const T &operator[] (size_type i) const { return data_[i]; }

    void push_back(const T &t);
    void swap(Vector &rhs)
    {
        std::swap(data_, rhs.data_);
        std::swap(avail_, rhs.avail_);
        std::swap(limit_, rhs.limit_);
    }

    size_type size() const { return avail_ - data_; }
    size_type capacity() const { return limit_ - data_; }

    iterator begin() { return data_; }
    const_iterator begin() const { return data_; }
    iterator end() { return avail_; }
    const_iterator end() const { return avail_; }

    reverse_iterator rbegin() { return reverse_iterator(end()); }
    const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
    reverse_iterator rend() { return reverse_iterator(begin()); }
    const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }

private:
    iterator data_; //首元素
    iterator avail_; //末尾元素的下一个位置
    iterator limit_; //内存的后面一个位置

    std::allocator<T> alloc_; //内存分配器

    void create();
    void create(size_type, const T &);
    void create(const_iterator, const_iterator);

    void uncreate();

    void grow();
    void uncheckedAppend(const T &);
};

template <typename T>
Vector<T> &Vector<T>::operator=(const Vector &rhs)
{
    if(this != &rhs)
    {
        uncreate(); //释放原来的内存
        create(rhs.begin(), rhs.end());
    }

    return *this;
}

template <typename T>
void Vector<T>::push_back(const T &t)
{
    if(avail_ == limit_)
    {
        grow();
    }
    uncheckedAppend(t);
}

template <typename T>
void Vector<T>::create()
{
    //分配空的数组
    data_ = avail_ = limit_ = 0;
}

template <typename T>
void Vector<T>::create(size_type n, const T &val)
{
    //分配原始内存
    data_ = alloc_.allocate(n);
    limit_ = avail_ = data_ + n;
    //向原始内存填充元素
    std::uninitialized_fill(data_, limit_, val);
}

template <typename T>
void Vector<T>::create(const_iterator i, const_iterator j)
{
    data_ = alloc_.allocate(j-i);
    limit_ = avail_ = std::uninitialized_copy(i, j, data_);
}

template <typename T>
void Vector<T>::uncreate()
{
    if(data_)
    {
        //逐个进行析构
        iterator it = avail_;
        while(it != data_)
        {
            alloc_.destroy(--it);
        }

        //真正的释放内存
        alloc_.deallocate(data_, limit_ - data_);
    }
    //重置指针
    data_ = limit_ = avail_ = 0;
}

template <typename T>
void Vector<T>::grow()
{
    //内存变为两倍
    size_type new_size = std::max(2 * (limit_ - data_), std::ptrdiff_t(1));
    //分配原始内存
    iterator new_data = alloc_.allocate(new_size);
    //复制元素
    iterator new_avail = std::uninitialized_copy(data_, avail_, new_data);

    uncreate(); //释放以前的内存,以及析构元素

    data_ = new_data;
    avail_ = new_avail;
    limit_ = data_ + new_size;
}

template <typename T>
void Vector<T>::uncheckedAppend(const T &val)
{
    alloc_.construct(avail_++, val);
}

#endif  /* VECTOR_H_ */

 

测试代码如下:

#include "Vector.hpp"
#include <iostream>
#include <string>
using namespace std;

//测试const reverse迭代器
void print(const Vector<string> &vec)
{
    for(Vector<string>::const_reverse_iterator it = vec.rbegin();
        it != vec.rend();
        ++it)
    {
        cout << *it << " ";
    }
    cout << endl;
}

int main(int argc, char const *argv[])
{
    Vector<string> vec(3, "hello");

    for(Vector<string>::const_iterator it = vec.begin();
        it != vec.end();
        ++it)
    {
        cout << *it << " ";
    }
    cout << endl;

    cout << "size = " << vec.size() << endl;
    cout << "capacity = " << vec.capacity() << endl;
    vec.push_back("foo");
    vec.push_back("bar");

    cout << "size = " << vec.size() << endl;
    cout << "capacity = " << vec.capacity() << endl;

    for(Vector<string>::reverse_iterator it = vec.rbegin();
        it != vec.rend();
        ++it)
    {
        cout << *it << " ";
    }
    cout << endl;

    print(vec);

    Vector<string> vec2;
    vec2.push_back("beijing");
    vec2.push_back("shanghai");
    vec2.push_back("guangzhou");
    print(vec2);

    vec.swap(vec2);
    print(vec);
    print(vec2);

    return 0;
}
时间: 2024-10-29 19:07:10

Vector的一种实现(二)的相关文章

Java的23种设计模式 &lt;二&gt;

1.单例模式(Singleton Pattern) 定义:Ensure a class has only one instance, and provide a global point of access to it.(确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.) 通用代码:(是线程安全的) public class Singleton { private static final Singleton singleton = new Singleton(); //限制产

vector的几种初始化和遍历

随着C++11标准的出现,vector出现了新的初始化和遍历用法,但是vs2010和较高版本并没有能完全支持C++11标准,所以我就将它的所有的用法归纳了一下. vector的初始化 vector基本初始化如下: vector< T >v1 v1是一个空的vector vector< T >v2(v1) v2包含v1所有元素,等价于vector v2=v1; vector< T >v3(n,val) v3包含了n个重复元素,每个元素是val 在C++11标准中出现了下面

7、二种 为二个不同的子网配置DHCP服务器

环境如下:        (参考之前,保证二个子网可以互相ping通) 虚拟机vm1        192.168.170.3                    VMnet8 (NAT模式) 虚拟机vm2        192.168.155.3                    VMnet1 (仅主机模式) 虚拟机gate        192.168.170.4 (eth1)       VMnet8 (NAT模式) 192.168.155.4 (eth0)       VMnet1

一种基于二维码的半自动文件拷贝方法

在一种受限的环境中,要把文件拷贝出去显然是不可能的.因为既不能进行直接的文本拷贝(Ctrl+C, Ctrl+V),又不能使用scp(因为网络隔离).那么,真的一点办法都木有了吗?答案是否定的,因为毛主席说过,"卑贱者最聪明,高贵者最愚蠢".作为一个好琢磨的程序员,因为好奇("与天斗,其乐无穷:与地斗,其乐无穷:与人斗,其乐无穷."),所以很快想出了一个解决的办法,那就是利用非常盛行的二维码技术.虽然全自动拷贝不好实现,但半自动拷贝还是非常容易做到的.于是,本文尝试利

STL vector的N种构造方式

1 使用默认无参的构造函数进行构造 vector<int> intVect; 观察内存可以看到生成一个带有0个元素的vector时内存中_Myfirst _Mylast _Myend的值均为0,说明vector对象并没有在堆中分配任何存储空间,仅仅是在栈中分配了16字节存储vecotr对象元素,在这16字节中前4字节如果没猜错,应该是一个虚表指针. Vecotr模版类有三个成员变量 _Myfirst  记录在堆分配数组的首地址 _Mylast  记录在堆中分配数组中最后一个有效数据的下一字节地

Vector的一种实现

  注意几点: 分配内存不要使用new和delete,因为new的同时就把对象构造了,而我们需要的是原始内存. 所以应该使用标准库提供的allocator类来实现内存的控制.当然也可以重载operator new操作符,因为二者都是使用malloc作为底层实现,所以直接采用malloc也可以. 对象的复制必须使用系统提供的uninitialized_fill和uninitialized_copy,因为我们无法手工调用构造函数. 对于C++中的对象,除了POD之外,使用memcpy系列的函数是绝对

【进阶EJB】深入探讨三种Bean(二)——Entity Bean

通过上一篇文章,我们介绍了[进阶EJB]深入探讨三种Bean(一)--Session Bean,这篇文章继续介绍EJB的三种Bean,今天我们重点介绍一下Entity Bean. Entity Bean,通过名字我们就知道是实体Bean是存放数据的.Entity Bean是持久化的数据组件,代表持久存储的商业实体对象.通常情况下,每个Entity Bean对应于关系数据库中的单张表,Entity Bean的单个实例对应于表中的某一条数据.上篇文章中说的Session Bean可作为Entity

C语言:指针的几种形式二

一.const指针 1.const int* p和int const* p:两者意义是相同的.指向的内容是只读数据,不可以q改变:但是指向的地址可以改变. 2.int* const p:必须先对指针初始化,而且指向的地址是只读的,不可以再被改变:但是指向的内容可以改变. 3.const int* const p:既不可以改变指针指向的地址,也不可以改变指针指向的内容. 二.指针数组:元素类型全是指针 类型名称*数组名[数组长度] 例如: char* pc[10]:字符指针数组,常用来可以表示一个

Vector 的五种遍历方式

via http://blog.csdn.net/ls306196689/article/details/35787955 方式三用时最短 方式一 for (size_t i =0; i < vec.size(); i ++) { int d = vec[i]; } 方式二 size_t len = vec.size(); for (size_t i =0; i < len; i ++) { int d = vec[i]; } 方式三   for (auto it = vec.begin();