【C++】模拟实现vector

可以把vector看作升级版的数组,可采用下标进行访问,非常高效,大小可动态改变,会自动扩容,数据存储在堆空间上。

VECROR

成员变量、函数及模板总览

cpp 复制代码
namespace ahunb{

  template<class T>
  class vector
  {
  public:

    // Vector的迭代器是一个指针 //
      
    typedef T* iterator;
        
    typedef const T* const_iterator;
        
	/ Iterators /
        
    iterator begin();

    iterator end();

    const_iterator cbegin();

    const_iterator cend() const;

    // construct and destroy 

    vector();

    vector(int n, const T& value = T());

    template<class InputIterator>

    vector(InputIterator first, InputIterator last);

    vector(const vector<T>& v);

    vector<T>& operator= (vector<T> v);

    ~vector();

    / capacity /

    size_t size() const ;

    size_t capacity() const;

    void reserve(size_t n);

    void resize(size_t n, const T& value = T());



    ///Element access//

    T& operator[](size_t pos);

    const T& operator[](size_t pos)const;



    ///modifiers/

    void push_back(const T& x);

    void pop_back();

    void swap(vector<T>& v);

    iterator insert(iterator pos, const T& x);

    iterator erase(Iterator pos);

  private:
    iterator _start; // 指向数据块的开始
    iterator _finish; // 指向有效数据的尾
    iterator _endOfStorage; // 指向存储容量的尾

  };

构造函数和析构函数

无参构造函数

cpp 复制代码
vector()
{}

构造n个元素大小的空间并初始化

cpp 复制代码
vector(int n, const T& value = T())
{
    resize(n);
    for (int i = 0; i < n; i++)
    {
        vector[i] = value;
    }
}

通过某个对象的两个迭代器来构造

cpp 复制代码
template<class InputIterator>
    vector(InputIterator first, InputIterator last)
{
    while (first != last)
    {
        push_back(*first);
        first++;
    }
}

拷贝构造函数

cpp 复制代码
vector(const vector<T>& v)
{
    reserve(v.capacity());
    for (auto e : v)
    {
        push_back(e);
    }
}

赋值运算符重载

cpp 复制代码
vector<T>& operator= (vector<T> v)
{
    swap(v);
    return *this;
}

析构函数

cpp 复制代码
~vector()
{
    delete[] _start;
    _start = _finish = _endofstorage = nullptr;
}

迭代器

返回第一个元素迭代器

多提供一个加const的 ,以防有const对象要调用

cpp 复制代码
iterator begin()
{
	return _start;
}
const_iterator begin() const
{
    return _start;
}

返回最后一个元素迭代器

cpp 复制代码
iterator end()
{
    return _finish;
}
const_iterator end() const
{
    return _finish;
}

容量和大小相关函数

返回当前大小

cpp 复制代码
size_t size()
{
    return _finish - _start;
}
const size_t size() const 
{
    return _finish - _start;
}

返回当前容量上限

cpp 复制代码
size_t capacity()
{
    return _endofstorage - _start;
}

const size_t capacity() const
{
    return _endofstorage - _start;
}

reserve函数

改变vector的capacity(容量)变量

当n>capacity将capacity改为n,否则不变

对新空间进行拷贝时要深拷贝,否则delete时会出现野指针

cpp 复制代码
void reserve(size_t n)
{
    if (n > capacity())
    {
        int sz = size();
        iterator tmp = new T[n];
        if (_start)
        {
            for (int i = 0; i < sz; i++)
            {
                tmp[i] = _start[i];//注意使用深拷贝
            }
            delete[]  _start;
        }
        _start = tmp;
        _finish = _start + sz;
        _endofstorage = _start+n;
    }
}

resize函数

改变vector的size(当前大小)变量

当n>size时,将大小改为n,并将新增加的大小初始化

否则直接将大小改为n就可以

cpp 复制代码
void resize(size_t n, const T& value = T())
{
    if (n > size())
    {
        reserve(n);
        while (_finish < _start + n)
        {
            *_finish = value;
            _finish++;
        }
    }
    else
    {
        _finish = _start + n;
    }
}

访问元素接口

[ ]运算符重载

cpp 复制代码
T& operator[](size_t pos)
{
    assert(pos < size());
    return _start[pos];
}

const T& operator[](size_t pos)const
{
    assert(pos < size());
    return _start[pos];
}

添加元素与删除元素

尾插

cpp 复制代码
void push_back(const T& x)
{
    if (_finish == _endofstorage)
    {
        int cp = capacity();
        cp = (cp == 0 ? 4 : cp * 2);
        reserve(cp);
    }
    *_finish = x;
    ++_finish;
}

指定位置插入元素

  • 注意扩容之后会存在pos失效问题,因为扩容之后原对象改变了_start等指针,指向了新的区间,但pos指向的还是原来的区间,所以在第七行和第九行对pos进行了更新。
cpp 复制代码
iterator insert(iterator pos, const T& x)
{
    assert(pos <= finish);
    assert(pos >= _start);
    if (_finish == _endofstorage)
    {
        int n = pos - _start;
        reserve(capacity() + 1);
        pos = _start + n;
    }
    iterator end = _finish;
    while (end > pos)
    {
        *end = *(end - 1);
        end--;
    }
    *pos = x;
    _finish++;
    return pos;
}

删除指定位置元素

cpp 复制代码
iterator erase(iterator pos)
{
    assert(pos < finish);
    assert(pos >= _start);
    if (_finish - 1 != pos)
    {
        iterator begin = pos;
        while (begin < _finish - 1)
        {
            *begin = *(begin + 1);
        }
    }
    _finish--;
    return pos+1;
}

尾删

cpp 复制代码
void pop_back()
{
    erase(_finish - 1);
}

交换

cpp 复制代码
void swap(vector<T>& v)
{
    std::swap(_start, v._start);
    std::swap(_finish, v._finish);
    std::swap(_endofstorage, v._endofstorage);
}

源代码

cpp 复制代码
//vector.h
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <assert.h>


using namespace std;


namespace ahu 
{
	template <class T>
	class vector 
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;


		vector()
		{}


		vector(int n, const T& value = T())
		{
			resize(n);
			for (int i = 0; i < n; i++)
			{
				vector[i] = value;
			}
		}


		template<class InputIterator>
		vector(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				push_back(*first);
				first++;
			}
		}


		vector(const vector<T>& v)
		{
			reserve(v.capacity());
			for (auto e : v)
			{
				push_back(e);
			}
		}


		vector<T>& operator= (vector<T> v)
		{
			swap(v);
			return *this;
		}


		~vector()
		{
			delete[] _start;
			_start = _finish = _endofstorage = nullptr;
		}


		//Iterator
		iterator begin()
		{
			return _start;
		}
		iterator end()
		{
			return _finish;
		}
		const_iterator begin() const
		{
			return _start;
		}
		const_iterator end() const
		{
			return _finish;
		}


		//Capacity


		size_t size()
		{
			return _finish - _start;
		}
		const size_t size() const 
		{
			return _finish - _start;
		}


		size_t capacity()
		{
			return _endofstorage - _start;
		}


		const size_t capacity() const
		{
			return _endofstorage - _start;
		}


		void reserve(size_t n)
		{
			if (n > capacity())
			{
				int sz = size();
				iterator tmp = new T[n];
				if (_start)
				{
					for (int i = 0; i < sz; i++)
					{
						tmp[i] = _start[i];
					}
					delete[]  _start;
				}
				_start = tmp;
				_finish = _start + sz;
				_endofstorage = _start+n;
			}
		}


		void resize(size_t n, const T& value = T())
		{
			if (n > size())
			{
				reserve(n);
				while (_finish < _start + n)
				{
					*_finish = value;
					_finish++;
				}
				_finish = _start + n;
			}
			else
			{
				_finish = _start + n;
			}
		}


		//Element access
		T& operator[](size_t pos)
		{
			assert(pos < size());
			return _start[pos];
		}


		const T& operator[](size_t pos)const
		{
			assert(pos < size());
			return _start[pos];
		}


		//Modifiers
		void push_back(const T& x)
		{
			if (_finish == _endofstorage)
			{
				int cp = capacity();
				cp = (cp == 0 ? 4 : cp * 2);
				reserve(cp);
			}
			*_finish = x;
			++_finish;
		}


		void pop_back()
		{
			erase(_finish - 1);
		}


		void swap(vector<T>& v)
		{
			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_endofstorage, v._endofstorage);
		}


		iterator insert(iterator pos, const T& x)
		{
			assert(pos <= finish);
			assert(pos >= _start);
			if (_finish == _endofstorage)
			{
				int n = pos - _start;
				reserve(capacity() + 1);
				pos = _start + n;
			}
			iterator end = _finish;
			while (end > pos)
			{
				*end = *(end - 1);
				end--;
			}
			*pos = x;
			_finish++;
			return pos;
		}


		iterator erase(iterator pos)
		{
			assert(pos < finish);
			assert(pos >= _start);
			if (_finish - 1 != pos)
			{
				iterator begin = pos;
				while (begin < _finish - 1)
				{
					*begin = *(begin + 1);
				}
			}
			_finish--;
			return pos+1;
		}


	private:


		iterator _start = nullptr; // 指向数据块的开始
		iterator _finish = nullptr; // 指向有效数据的尾
		iterator _endofstorage = nullptr; // 指向存储容量的尾
	};
}

//vector.cpp
#define _CRT_SECURE_NO_WARNINGS
#include "vector.h"
//#include <vector>
using namespace ahu;
int main()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(1);
	v1.push_back(1);
	v1.push_back(1);
	v1.push_back(1);
	v1.push_back(1);
	v1.push_back(1);
	v1.push_back(1);
	//v1.push_back(1);


	vector<int> v2(v1);
	for (size_t i = 0; i < v2.size(); i++)
	{
		cout << v2[i] << endl;
	}
	cout << "-------------------------------------" << endl;


	//v2.reserve(100);
	//cout << v2.capacity() << endl;
	//cout << v2.size()<<endl;
	//v2.resize(50);
	//cout << v2.capacity() << endl;
	//cout << v2.size() << endl;
	//v2.reserve(25);
	//cout << v2.capacity() << endl;
	//cout << v2.size() << endl;
	v2.insert(v2.begin()+3, 100);
	for (size_t i = 0; i < v2.size(); i++)
	{
		cout << v2[i] << endl;
	}
	cout << "-------------------------------------" << endl;
	v2.erase(v2.begin() + 9);
	v2.erase(v2.begin() + 8);
	v2.erase(v2.begin() + 7);
	v2.erase(v2.begin() + 6);
	v2.erase(v2.begin() + 5);
	v2.erase(v2.begin() + 4);
	v2.erase(v2.begin()+3);
	for (size_t i = 0; i < v2.size(); i++)
	{
		cout << v2[i] << endl;
	}
}

✨本文收录于C++语法及练习

当你喜欢一篇文章时,点赞、收藏和关注是最好的支持方式。如果你喜欢我的文章,请不要吝啬你的支持,点赞👍、收藏⭐和关注都是对我最好的鼓励。感谢你们的支持!如有问题欢迎指正!

相关推荐
legend_jz10 分钟前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法
嘿BRE19 分钟前
【C++】几个基本容器的模拟实现(string,vector,list,stack,queue,priority_queue)
c++
ö Constancy1 小时前
c++ 笔记
开发语言·c++
fengbizhe1 小时前
笔试-笔记2
c++·笔记
徐霞客3201 小时前
Qt入门1——认识Qt的几个常用头文件和常用函数
开发语言·c++·笔记·qt
fpcc1 小时前
redis6.0之后的多线程版本的问题
c++·redis
螺旋天光极锐斩空闪壹式!2 小时前
自制游戏:监狱逃亡
c++·游戏
工业3D_大熊3 小时前
3D可视化引擎HOOPS Luminate场景图详解:形状的创建、销毁与管理
java·c++·3d·docker·c#·制造·数据可视化
暮色_年华3 小时前
Modern Effective C++ Item 11:优先考虑使用deleted函数而非使用未定义的私有声明
c++
流星白龙3 小时前
【C++习题】10.反转字符串中的单词 lll
开发语言·c++