Vector简单实现第二版

#include <iostream>
#include <memory>
#include <algorithm>
#include <initializer_list>
#include <stdexcept>
using namespace std;

template <class T, class A=allocator<T> >
struct vector_base {
	A alloc;
	T* elem;
	T* space;
	T* last;
	
	vector_base(const A& a,typename A::size_type n)
		:alloc{a}, elem{alloc.allocate(n)}, space{elem+n}, last{elem+n} {}
	~vector_base() {alloc.deallocate(elem, last-elem);}
	
	vector_base(const vector_base&) = delete;
	vector_base& operator=(const vector_base&) = delete;
	
	vector_base(const vector_base&& a);
	vector_base& operator=(const vector_base&& a);
};

template <class T, class A>
vector_base<T,A>::vector_base(const vector_base&& a)
	:alloc{a.alloc},elem{a.elem},space{a.space},last{a.space}
{
	a.elem = a.space = a.last = nullptr;
}

template <class T, class A>
vector_base<T,A>& vector_base<T,A>::operator=(const vector_base&& a)
{
	swap(*this, a);
	return *this;
}

template <class T, class A=allocator<T> >
class Vector {
	public:
		using size_type = unsigned int;
		explicit Vector(size_type n,const T& val=T(),const A& a=A());
		explicit Vector(initializer_list<T> lst, const A& a=A());
		Vector(const Vector& a);
		Vector& operator=(const Vector& a);
		Vector(Vector&& a);
		Vector& operator=(Vector&& a);
		~Vector() {delete_elements();}
		
		size_type size() const {return vb.space-vb.elem;}
		size_type capacity() const {return vb.last-vb.elem;}
		void reserve(size_type newalloc);
		void resize(size_type newsize, const T& val=T());
		void clear() {resize(0);}
		void push_back(const T& val);
		
		T* begin() {return vb.elem;}
		const T* begin() const {vb.elem;}
		T* end() {return vb.space;}
		const T* end() const {return vb.space;}
		T& operator[](size_type p);
	private:
		void delete_elements();
	private:
		vector_base<T,A> vb;
};

template <class T, class A>
void Vector<T,A>::delete_elements()
{
	for(T* p=begin(); p!=end(); p++)
		p->~T();
	vb.space = vb.elem;
}

template <class T, class A>
Vector<T,A>::Vector(size_type n,const T& val,const A& a):vb{a,n}
{
	uninitialized_fill(begin(), end(), val);
}

template <class T, class A>
Vector<T,A>::Vector(initializer_list<T> lst, const A& a):vb{a, lst.size()}
{
	uninitialized_copy(lst.begin(), lst.end(), begin());
}

template <class T, class A>
Vector<T,A>::Vector(const Vector& a):vb{a.vb.alloc, a.size()}
{
	uninitialized_copy(a.begin(), a.end(), begin());
}

template <class T, class A>
Vector<T,A>& Vector<T,A>::operator=(const Vector& a)
{
	if (capacity() < a.size())
	{
		Vector<T,A> temp{a};
		swap(*this, temp);
		return *this;
	}
	if (*this == a) return *this;
	
	size_type asz = a.size();
	size_type sz = size();
	if (asz < sz)
	{
		copy(a.begin(), a.end(), begin());
		for(T* p=begin()+asz; p!=end(); p++)
			p->~T();
	}else {
		copy(a.begin(), a.begin()+sz, begin());
		uninitialized_copy(a.begin()+sz, a.end(), end());
	}
	vb.space = vb.elem + asz;
	return *this;
}

template <class T, class A>
Vector<T,A>::Vector(Vector&& a):vb{std::move(a.vb)}
{
	
}

template <class T, class A>
Vector<T,A>& Vector<T,A>::operator=(Vector&& a)
{
	clear();	//销毁对象 
	swap(*this ,a);
	return *this;
}

template <class T, class A>
void Vector<T,A>::reserve(size_type newalloc)
{
	if (newalloc <=capacity()) return;
	vector_base<T,A> b{vb.alloc, newalloc};
	for(T* p=begin(), oo=b.elem; p!=end(); p++,oo++)
	{
		new (static_cast<void*>(&*oo)) T(move(*p));
		p->~T();
	}
	//调整size 
	b.space = b.elem + size();
	swap(vb, b);
}

template <class T, class A>
void Vector<T,A>::resize(size_type newsize, const T& val)
{
	reserve(newsize);
	if (newsize > size())
		uninitialized_fill(begin()+size(), begin()+newsize, val);
	else {
		for(T* p=begin()+newsize; p!=end(); p++)
			p->~T();
	}
	//调整size,capacity无需调整 
	vb.space = vb.elem + newsize;
}

template <class T, class A>
void Vector<T,A>::push_back(const T& val)
{
	if (size() == capacity())
		reserve(capacity() ? capacity()*2 : 8);
	vb.alloc.construct(vb.elem+size(), val);
	vb.space++;
}

template <class T, class A>
T& Vector<T,A>::operator[](size_type p)
{
	if (p >= size())
		throw out_of_range{"数组越界"};
	return vb.elem[p];
}

int main()
{
	Vector<int> ivec{1,2,3,4,5};
	for(auto i : ivec)
		cout << i << endl;
}

感觉很不错,需要多加练习,多加理解。

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:1024 设计师:我叫白小胖 返回首页
评论

打赏作者

明天过后mm

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值