简单vector实现

参考 c++ primer 5th ,stl 源码剖析


// myVector.cpp : 简单的vector实现。
//
#include "stdafx.h"
#include <iostream>
#include <initializer_list>
#include <algorithm>
using namespace std;

template< typename T>
class Vector {
public:
     typedef T value_type;
     typedef value_type* pointer_type;
     typedef value_type* iterator;
     typedef value_type& reference;
     typedef std::ptrdiff_t difference_type;
     typedef std::size_t size_type;

     Vector():start(nullptr),finish(nullptr),end_of_storage(nullptr){ }
     Vector(size_type n, const T& value) { fill_initialize(n, value); }
     Vector(int n, const T& value) { fill_initialize(n, value); }
     Vector(long n, const T& value) { fill_initialize(n, value); }
     explicit Vector(size_type n){ fill_initialize(n, T()); }
     Vector(std::initializer_list< T>);
     Vector(const Vector&);
     Vector & operator=( const Vector&);
     ~Vector();

     iterator begin() const{ return start; }
     iterator end() const{ return finish; }

     void push_back(const T&);

     reference operator[] ( size_type n) { return *( begin() + n); }
     bool empty() const { return begin() == end(); }
     size_type size() const{ return finish - start; }
     size_type capacity() const{ return end_of_storage - start; }

     void reserve(size_type newsize);
     void resize(size_type newsize);
     void resize(size_type newsize,const T& t);

     void insert(iterator position, size_type n, const T& x);
     iterator erase(iterator position)
     {
            if ( position + 1 != end())
           {
                 copy( position + 1, finish, position);
           }
           -- finish;
            alloc. destroy( finish);
            return position;
     }

     void pop_back()
     {
            alloc. destroy(-- finish);
     }

     reference back() {
            return *( end() - 1);
     }

     reference front() {
            return * begin();
     }

private:
     iterator start;
     iterator finish;
     iterator end_of_storage;

     std::allocator<T> alloc;
     void chk_n_alloc()
     {
            if ( size() == capacity())
           {
                 reallocate();
           }
     }

     void reallocate();
     void free();

     void _alloc_n_move(size_type n);
     iterator _allocate_and_fill(size_type n,const T& x);
     void fill_initialize(size_type n, const T& value)
     {
            start = _allocate_and_fill( n, value);
            finish = start + n;
            end_of_storage = finish;
     }
};

template< typename T>
Vector< T>:: Vector( initializer_list< T> l)
{
     T * const NewData = alloc.allocate(l.size());
     T *p = NewData;
     for (const auto &ele : l)
            alloc. construct( p++, ele);

     start = NewData;
     finish = end_of_storage = start + l.size();
}

template< typename T>
Vector< T>:: Vector( const Vector& rhs)
{
     T *newData = alloc.allocate(rhs.end() - rhs.begin());
     std::uninitialized_copy( rhs. begin(), rhs. end(), newData);
     start = newData;
     finish = end_of_storage = start + rhs.size();
}

template< typename T>
Vector< T> & Vector< T>::operator=( const Vector& rhs)
{
     T *newData = alloc.allocate(rhs.end() - rhs.begin());
     std::uninitialized_copy( rhs. begin(), rhs. end(), newData);
     free();
     start = newData;
     finish = end_of_storage = start + rhs.size();
     return *this;
}

template< typename T>
Vector< T>::~ Vector()
{
     free();
}

template< typename T>
void Vector< T>:: reallocate()
{
     std::size_t newCapacity = size() ? 2 * size() : 1;
     _alloc_n_move(newCapacity);
}

//tool-function move element to new place which size is n
template< typename T>
void Vector< T>:: _alloc_n_move( size_type n){
     T *newAddr = alloc.allocate(n);
     T *des = newAddr;
     T *old = start;
     for (size_type i = 0; i != size(); ++i)
            alloc. construct( des++, std:: move(* old++));

     free();
     start = newAddr;
     finish = des;
     end_of_storage = start + n;
}

template< typename T>
void Vector< T>:: free() {
     if (start)
     {
            for ( auto it = finish; it != start;)
                 alloc. destroy(-- it);
            alloc. deallocate( start, capacity());
     }
}

template< typename T>
void Vector< T>:: push_back( const T& value)
{
     chk_n_alloc();
     alloc.construct(finish++, value);
}

template< typename T>
void Vector< T>:: reserve( size_type newsize)
{
     if (newsize > capacity())
     {
            _alloc_n_move( newsize);
     }
}

template< typename T>
void Vector< T>:: resize( size_type newsize, const T& t)
{
     if (newsize > capacity())
     {
            for ( auto i = size(); i != newsize; ++ i)
                 push_back( t);
     }
     else{
            for ( auto p = start + newsize; p != finish;)
                 alloc. destroy( p++);
            finish = start + newsize;
     }
}

template< typename T>
void Vector< T>:: resize( size_type newsize)
{
     resize(newsize, T());
}

template< typename T>
typename Vector< T>:: iterator Vector< T>:: _allocate_and_fill( size_type n, const T& x)
{
     iterator result = alloc.allocate(n);
     uninitialized_fill_n( result, n, x);
     return result;
}


template< typename T>
void Vector< T>:: insert( iterator position, size_type n, const T& x)
{
     if (n != 0) {
            if ( size_type( end_of_storage - finish) >= n) {
                 //备用空间大于新增元素
                 T x_copy = x;
                 //计算插入点之后的现有元素个数
                 const size_type elems_after = finish - position;
                 iterator old_finish = finish;
                 if ( elems_after > n) {
                      uninitialized_copy( finish - n, finish, finish);
                      finish += n;
                      copy_backward( position, old_finish - n, old_finish);
                      fill( position, position + n, x_copy);
                }
                 else {
                      //插入点之后的现有元素个数 小于等于 新增元素个数
                      uninitialized_fill_n(finish , n - elems_after, x_copy);
                      finish += n - elems_after;
                      uninitialized_copy( position, old_finish, finish);
                      finish += elems_after;
                      fill( position, old_finish, x_copy);
                      //uninitialized_fill_n(position, elems_after, x_copy);
                }
           }
            else {
                 //备用空间小于 新增元素个数,须配置额外内存
                 //首先决定新长度:旧长度的两倍或者旧长度+新增元素个数
                 const size_type old_size = size();
                 const size_type len = old_size + max( old_size, n);
                 iterator new_start = alloc. allocate( len);
                 iterator new_finish = new_start;

                 new_finish = uninitialized_copy( start, position, new_start);
                 new_finish = uninitialized_fill_n(new_finish , n , x);
                 new_finish = uninitialized_copy( position, finish, new_finish);
                 for ( auto iter = start; iter != finish;)
                      alloc. destroy( iter++);
                 alloc. deallocate( start, end_of_storage - start);
                 start = new_start;
                 finish = new_finish;
                 end_of_storage = new_start + len;
           }
     }
}

int _tmain( int argc, _TCHAR* argv[])
{
     Vector<int> vec;
     vec.push_back(1);
     vec.push_back(2);
     Vector<int> v = { 2, 3, 45, 6, 7 };
     vec = v;
     v.push_back(111);
     Vector<int> v2(v);
     for (auto e : v2)
            cout << e << '\t';
     cout << endl;
     //cout << vec.capacity() << endl;
     //cout << vec.size() << endl;
     vec.pop_back();
     vec.pop_back();
     for (auto e : vec)
            cout << e << '\t';
     cout << endl;
     //cout << "front " << vec.front() << endl;
     //cout << "back " << vec.back() << endl;
     vec.insert(vec.end(), 3, 2);
     for (auto e : vec)
            cout << e << '\t';
     cout << endl;
     return 0;
}
  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值