C++中vector的实现



注意几点:

分配内存不要使用new和delete,因为new的同时就把对象构造了,而我们需要的是原始内存。

所以应该使用标准库提供的allocator类来实现内存的控制。当然也可以重载operator new操作符,因为二者都是使用malloc作为底层实现,所以直接采用malloc也可以。

对象的复制必须使用系统提供的uninitialized_fill和uninitialized_copy,因为我们无法手工调用构造函数。

对于C++中的对象,除了POD之外,使用memcpy系列的函数是绝对错误的。

myvector.h

#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_;
        };

        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);

        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());}
        reverse_iterator rend() {return reverse_iterator(begin());}

        void swap(Vector &rhs)
        {
            std::swap(data_, rhs.data_);
            std::swap(avail_, rhs.avail_);
            std::swap(limit_, rhs.limit_);
        }
    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 uncheckAppend(const T &);
};

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

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

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

    template <typename T>
inline 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>
inline 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>
inline 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>
inline void Vector<T>::grow()
{
    //内存变为2倍
    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>
inline void Vector<T>::uncheckAppend(const T &val)
{
    alloc_.construct(avail_++, val);
}

#endif /*VECTOR_H*/ 

test_main.cpp

#include "myvector.h"
#include <iostream>
#include <string>
using namespace std;

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

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

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

    for(Vector<string>::const_iterator it = vec.begin();
        it != vec.end();
        ++it)
    {
        cout << *it << endl;
    }
   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;

   print_reverse(vec);
   print(vec);
    return 0;
}

转自:http://www.cnblogs.com/inevermore/p/4003710.html



时间: 2024-12-23 07:26:13

C++中vector的实现的相关文章

C++中vector reserve和resize函数

1.reserve 当内存受限时(此时虚拟内存都快耗尽),由于push_back由于每次发现存储空间不够时,默认会申请原来空间的两倍,此时申请空间时就会发生错误.因此如果知道 vector需要多少内存的话,最好先用 reserve申请一下空间 ,即预申请一定的空间. 2.resize 重新设置该容器的大小 <span style="font-size:14px;">// test_max.cpp : 定义控制台应用程序的入口点. #include "stdafx.

ogqvcC++中vector和链表插入问题

叔滨劐 ogqvcC++中vector和链表插入问题

Java中vector的使用方法

Vector的使用 vector类底层数组结构的,它包含可以使用整数索引进行访问的组件.不过,vector的大小可以根据需要增大或缩小,以适应创建vector后进行添加或移除项的操作,因此不需要考虑元素是否越界或者会不会浪费内存的问题. 由vector的iterator和listIterator方法所返回的迭代器是快速失败的:也即是它不能并发执行操作.如果在迭代器创建后的任意时间从结构上修改了向量(通过迭代器自身的remove或add方法之外的任何其他方式),则迭代器将抛出ConcurrentM

关于C++中vector和set使用sort方法进行排序

C++中vector和set都是非常方便的容器, sort方法是algorithm头文件里的一个标准函数,能进行高效的排序,默认是按元素从小到大排序 将sort方法用到vector和set中能实现多种符合自己需求的排序 首先sort方法可以对静态的数组进行排序 1 #include<iostream> 2 using namespace std; 3 int main(){ 4 int a[10] = { 9, 0, 1, 2, 3, 7, 4, 5, 100, 10 }; 5 sort(a,

Java中Vector和ArrayList的区别

首先看这两类都实现List接口,而List接口一共有三个实现类,分别是ArrayList.Vector和LinkedList.List用于存放多个元素,能够维护元素的次序,并且允许元素的重复. 3个具体实现类的相关区别如下: ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问.数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要讲已经有数组的数据复制到新的存储空间中.当从ArrayList的中间位置插入或者删除元素时,需要对数组

c++中vector的用法详解

c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的. 用法: 1.文件包含: 首先在程序开头处加上#include<vector>以包含所需要的类文件vector 还有一定要加上using namespace std; 2.变量声明: 2.1 例:声明一个int向量以替代一维的数组:vector <int> a;(等于声明了一个

java中vector和array区别

java中vector和数组非常类似,两者之间也经常成对出现,下面是两者的比较: 1.数组:java arrays的元素个数不能下标越界,从很大程度上保证了java程序的安全性,但创建时必须指定数组的大小,并不能再改变. 2.vector:对比于array,当更多的元素被加入进来以至超出其容量时,vector的size会动态增长,而array容量是定死的.同时,vector在删除一些元素后,其所有下标大于被删除元素的元素都依次前移,并获得新下标比原来的小了).

C++的STL中vector内存分配方法的简单探索

STL中vector什么时候会自动分配内存,又是怎么分配的呢? 环境:Linux  CentOS 5.2 1.代码 #include <vector> #include <stdio.h> using namespace std; int main() { vector<int> x_vec; printf("data size : [%3d], mem size : [%3d]\n", x_vec.size(), x_vec.capacity())

std中vector的实现原理(标准模板动态库中矢量的实现原理)

我们实现的数据结构是为了解决在运行过程中动态的开辟空间使用(例如我们不停的输入,输入的多少我们不确定) 原理两种: 一.笨办法 我们第一次用多少空间,开辟多少空间A 我们第二次用空间,会开辟大于第一次开辟的空间B,将A里的数据拷贝到B中,然后释放A,在C中写入新的数据 缺点:在于拷贝的次数太多,效率低 二.改进的办法 矢量有一个参数,里面填写预留的空间,加入我们填写的预留空间大小是B,这里是预留,并没有真正的开辟物理内存,预留的作用于如果这时候如果需要开辟空间做其他事情,开辟的空间会避开B,这样

(知识点4)C++ 中vector

1.定义vector<vector<int>> M; 2.添加元素这里是vector的嵌套使用,本质是vector元素里的每个元素也是vector类型,所以抓住本质来添加元素就比较容易理解. 我们假设外层的vector的对象为M,为外层vector对象,则M中的每一个元素也是vector类型,记为N1,N2,N3……,为内层对象 则,我们得先形成一个个的N1,N2等的vector对象,然后再将这些vector对象添加进入外层vector对象M中 这样就比较容易理解向vector&l