vector的简单实现

目录

vector的结构 

构造和析构 

 迭代器和容量相关的函数

扩容 

插入和删除

尾插和尾删 

 任意插入和任意删除

重载下标引用操作符和赋值运算符

operator=

operatro[ ]


vector的结构 

vector是一个类模板

	template<typename T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T& const_iterator;	
    private:
	    iterator _start = nullptr;
        iterator _end_of_sortage = nullptr;
		iterator _finish = nullptr;
	};

通过_start,_end_of_sortage,_finish这三个指针来控制vector

构造和析构 

构造

		vector() = default;//使编译器自动生成默认构造函数

		vector(size_t n,const T& val = T())
		{
			_start = new T[n];
			for (int i = 0; i < n; i++)
			{
				_start[i] = val;
			}
			_finish = _end_of_sortage = _start + n;
		}

		vector(const vector<T>& v)//拷贝构造
		{
			size_t len = v.size();
			iterator tmp = new T[len];
			memcpy(tmp, v._start, sizeof(T)*len);
			delete[] _start;
			_start = tmp;
			_end_of_sortage = _finish = _start + len;
		}

注意这里的拷贝构造是深拷贝,需要先开辟空间,再将要拷贝的vector的数据,拷贝进新开辟的空间。

析构

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

释放开辟的资源

 迭代器和容量相关的函数

		size_t size()
		{
			return _finish - _start;//两个指针相减结果是两指针之间元素的个数
		}
		size_t capacity()
		{
			return _end_of_sortage - _start;
		}

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

		iterator begin()
		{
			return _start;
		}
		iterator end()
		{
			return _finish;
		}

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


扩容 

		void reverse(size_t n)
		{
			if (n > capacity())
			{
				int oldsize = size();//记录原来的开辟空间的大小
				iterator tmp = new T[n];
				memcpy(tmp, _start, sizeof(T) * oldsize);//将原来的数据拷贝进新开辟的空间
				delete[] _start;
				_start = tmp;
				_finish = tmp + oldsize;
				_end_of_sortage = _start + n;
			}
		}

插入和删除

尾插和尾删 

		void push_back(const T& x)//尾插
		{
            //考虑是否需要扩容
			if (size() == capacity())
			{
				reverse(2 * capacity());
			}
			*_finish = x;
			_finish++;
		}

		void pop_back()//尾删
		{
			assert(size() > 0);
			_finish--;
		}

 任意插入和任意删除

		//
        iterator insert(iterator pos, const T& x)
		{
            //看是否需要扩容
			if (size() == capacity())
			{
				reverse(2 * capacity());
			}
			iterator end1 = end()-1;
            //将pos位置及其以后位置的元素整体向后挪一位
			while (end1 != pos+1)
			{
				*(end1+1) = *end1;
				end1--;
			}
			*(pos+1) = x;
            _end_of_sortage++;
			return pos+1;
		}

		iterator erase(iterator pos)
		{
			iterator cur = pos;
            //将pos之后的所有元素整体向前挪一位
			while(cur!=end()-1)
			{
				*cur = *(cur + 1);
				cur++;
			}
            _end_of_sortage--;
			return pos;
		}

注意insert和erase的返回值都是迭代器。

为什么会返回迭代器?

因为当插入或删除一个数据后,可能会导致迭代器失效的问题。

	vector<int> v = { 1,2,3,4,5,6,7 };
	vector<int>::iterator it = v.begin();
	vector<int>::iterator end = v.end();
	while (it != end)
	{
		if (*it == 3)
			v.erase(it);//删除一个3这个数据就会导致end指向的位置不在是vector容器的末尾end失效
		cout << *it << " ";
	}

 解决办法就是

	while (it != v.end())//实时更新
	{
		if (*it == 3)
			v.erase(it);
		cout << *it << " ";
	}

重载下标引用操作符和赋值运算符

operator=

		//原始写法
        vector<T>& operator=(const vector<T>& v)
		{
			reverse(v.capacity());
			memcpy(_start, v._start, sizeof(T) * v.size());
			_end_of_sortage = _start + v._size();
			//_finish = _start + v.capacity;
			return *this;
    	}		
        //现代写法
        vector<T>& operator=(const vector<T> v)
		{
			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_end_of_sortage, v._end_of_sortage);
			return *this;
		}

operatro[ ]

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

注意对下标的检查,下标不能越界访问。

完整代码在gitee:

刷题记录: 用来调试刷题是写的代码 (gitee.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值