vector的模拟实现+类型萃取

cpp的vector模拟实现

实现的接口
Member functions:

  • vector (const allocator_type& alloc = allocator_type());
  • ~vector();
  • vector& operator= (const vector& x);

Iterators:

  • begin()
  • end()

Capacity:

  • size()
  • resize()
  • capacity()
  • empty()

Element access:

  • operator[]
  • back()

Modifiers:

  • push_back
  • pop_back
  • insert
  • erase
  • swap
  • clear

特别的,学习了模板的全特化进行类型的萃取,针对深层次的深浅拷贝问题提高一定的效率。

  • T是内置类型(int)或浅拷贝自定义类型(Date),他们增容或者拷贝构造中,我们用memcpy是没有问题的。但是T是深拷贝的自定义类型,他们增容或者拷贝中,我们用memcpy是有问题的。
#pragma once
#include<iostream>
#include <cassert>
namespace YCB {

	//类型萃取
	struct TrueType {
		bool get() {
			return true;
		}
	};
	struct FalseType {
		bool get() {
			return false;
		}
	};
	template<typename T>
	struct TypeTraits  //else的情况,表示自定义类型或者深拷贝类型
	{
		typedef FalseType istPodType;
	};
	//以下为常用基本类型特化
	template<>
	struct TypeTraits< bool>			 
	{
		typedef TrueType     istPodType;
	};

	template <>
	struct TypeTraits< char>
	{
		typedef TrueType     istPodType;
	};

	template <>
	struct TypeTraits< unsigned char >
	{
		typedef TrueType     istPodType;
	};

	template <>
	struct TypeTraits< short>
	{
		typedef TrueType     istPodType;
	};

	template <>
	struct TypeTraits< unsigned short >
	{
		typedef TrueType     istPodType;
	};

	template <>
	struct TypeTraits< int>
	{
		typedef TrueType     istPodType;
	};

	template <>
	struct TypeTraits< unsigned int >
	{
		typedef TrueType     istPodType;
	};

	template <>
	struct TypeTraits< long>
	{
		typedef TrueType     istPodType;
	};

	template <>
	struct TypeTraits< unsigned long >
	{
		typedef TrueType     istPodType;
	};

	template <>
	struct TypeTraits< long long >
	{
		typedef TrueType     istPodType;
	};

	template <>
	struct TypeTraits< unsigned long long>
	{
		typedef TrueType     istPodType;
	};

	template <>
	struct TypeTraits< float>
	{
		typedef TrueType     istPodType;
	};

	template <>
	struct TypeTraits< double>
	{
		typedef TrueType     istPodType;
	};

	template <>
	struct TypeTraits< long double >
	{
		typedef TrueType     istPodType;
	};

	template <class _Tp>
	struct TypeTraits< _Tp*>
	{
		typedef TrueType     istPodType;
	};


	template<typename T>
	class vector
	{
	public:
		typedef T* iterator;
		iterator begin() {
			return _start;
		}
		iterator end() {
			return _finish;
		}

		//构造
		vector(size_t n = 0, T tmp = T())
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{
			reserve(n);
			for (int i = 0; i < n; i++) {
				_start[i] = tmp;
			}
			_finish = _start+n;
		}


		//拷贝构造(现代版)
		vector(const vector<T>& A) 
			:_start(nullptr)
			,_finish(nullptr)
			,_end_of_storage(nullptr)
		{
			vector<T>tmp(A.size());///先初始化
			this->swap(A);
			if (TypeTraits<T>::istPodType().get()) {
				memmove(_start, A._start, A.size() * sizeof(T));
			}
			else {
				for (int i = 0; i < A.size(); i++) {
					_start[i] = A._start[i];
				}
			}
			
		}
		//operator=赋值
		vector<T>& operator=(const vector<T>& v) {
			reserve(v.size());
			_finish = _start;///视为删除.
			if (TypeTraits<T>::istPodType().get()) {
				memmove(_start, v._start, v.size() * sizeof(T));
			}
			else {
				for (int i = 0; i < v.size(); i++) {
					_start[i] = v._start[i];
				}
			}
			return *this;
		}

		//交换函数
		void swap(vector<T>& B) {
			std::swap(_start, B._start);
			std::swap(_finish, B._finish);
			std::swap(_end_of_storage, B._end_of_storage);
		}
		///开辟空间
		//类型萃取
		void reserve(size_t n) {
			if (n >= capacity()) {
				T* tmp = new T[n];
				assert(tmp);
				size_t len = size();
				//如果是内置类型(如int)
				if (TypeTraits<T>::istPodType().get() ) {
					memmove(tmp, _start, len * sizeof(T));
				}
				else {
					for (int i = 0; i < len; i++) {
						tmp[i] = _start[i];///调用operator=赋值(深拷贝)
					}
				}
				delete[] _start;
				_start = tmp;
				_finish = _start + len;
				_end_of_storage = _start + n;
			}
		}
		void resize(size_t n, T val = T()) {
			if (n > capacity()) { ///开到capacity()==n
				reserve(n);
			}
			if (n <= size()) {
				_finish = _start + n;
			}
			else {
				size_t res = n - size();
				for (int i = 0; i < res; i++) {
					push_back(val);
				}
				_finish = _start + n;
			}
		}
		//An iterator that points to the first of the newly inserted elements.
		iterator insert(iterator pos, const T& val) {
			if (size() == capacity()) {
				reserve((capacity() == 0 ? 4 : capacity() * 2)); ///防止多此扩容
			}
			iterator tmp = _finish ;
			while (tmp > pos) {
				*tmp = *(tmp - 1);
				tmp--;
			}
			*pos = val;
			_finish++;
			return pos;
		}
		iterator erase(iterator pos) {
			assert(pos < _finish&& pos >=_start);
			iterator tmp = pos;
			while (tmp +1  < _finish) {
				*tmp = *(tmp + 1);
				tmp++;
			}
			_finish--;
			assert(_finish >= _start);
			//An iterator pointing to the new location of the element that followed the last element erased by the function call.
			return pos;
		}

		//[first,last)
		iterator erase(iterator first, iterator last) {
			assert(first >= _start);
			iterator pos = first;
			if (last >= _finish) {
				_finish = first;
			}
			else {
				iterator tmp= last;
				while (tmp != _finish) {
					_start[first] = _start[tmp];
					first++;
					tmp++;
				}
				_finish = first;
				
			}
			return pos;
		}


		void push_back(const T& val) {
			if (_finish == _end_of_storage) reserve( (capacity() == 0 ? 4 : capacity() * 2) );//减少扩容次数
			*_finish = val;
			_finish++;
		}
		void pop_back(){
			_finish--;
			assert(_finish>=_start);
		}

		void clear() {
			_finish = _start;
		}

		bool empty() const {
			return (_start == _finish);
		}

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

		size_t capacity() const {
			return _end_of_storage - _start;
		}
		T& back()  {
			if (_start == _finish) return _start[0];
			else return *(_finish - 1);
		}

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

		T& operator[](const size_t& pos) const {
			assert(pos < size());
			return _start[pos];
		}
		//析构
		~vector() {
			delete[] _start;
			_finish = _end_of_storage = nullptr;
		}

	private:
		T* _start;
		T* _finish;
		T* _end_of_storage;
	};

	void test_vector1() {
		vector<int>v1;
		vector<int>v2(5,0);
		vector<double>v3(10, 2.3);
		cout << v1.size() << endl;
		for (int i = 0; i < v1.size(); i++) {
			cout << v1[i] << " ";
		}cout << endl;

		cout << v2.size() << endl;
		for (int i = 0; i < v2.size(); i++) {
			v2[i] += 1;
			cout << v2[i] << " ";
		}cout << endl;

		cout << v3.size() << endl;
		for (int i = 0; i < v3.size(); i++) {
			cout << v3[i] << " ";
		}cout << endl;


		vector<int>v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);

		vector<int>::iterator it = v.begin();
		while (it != v.end()) {
			*it += 1;
			cout << *it << endl;
			++it;
		}
	}

	void test_vector2() {
		vector<string>v1(2, std::string("zstu"));
		
		//vector<string>v2(4, "http://www.zstu.edu.cn/");

		cout << v1.size() << endl;
		for (auto &i : v1) {
			cout << i << " ";
		}cout << endl;

		/*cout << v2.size() << endl;
		for (auto& i : v2) {
			cout << i << " ";
		}cout << endl;*/

		v1.push_back("zzzzzzzzzzzzzzzzzz");
		v1.push_back("ssssssssssssssssss");
		v1.push_back("tttttttttttttttttt");
		v1.push_back("uuuuuuuuuuuuuuuuuu");
		cout << v1.size() << endl;
		vector<string>::iterator it = v1.begin();
		while (it != v1.end())
		{
			cout << (*it) << "			";
			cout << endl;
			it++;
		}cout << endl;
	}
	void test_vector3() {
		vector<int>v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.pop_back();
		v.pop_back();
		cout << v.size() << " " << v.capacity() << endl;
		for (auto &i : v) {
			cout << i << " ";
		}cout << endl;

		v.resize(3);
		cout << v.size() << " " << v.capacity() << endl;
		for (auto& i : v) {
			cout << i << " ";
		}cout << endl;

		v.resize(6, 1);
		cout << v.size() << " " << v.capacity() << endl;
		for (auto& i : v) {
			cout << i << " ";
		}cout << endl;

		v.resize(10, 2);
		cout << v.size() << " " << v.capacity() << endl;
		for (auto& i : v) {
			cout << i << " ";
		}cout << endl;
	}

	void test_vector4() {
		vector<int>v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5);

		cout << v.size() << " " << v.capacity() << endl;
		for (auto& i : v) {
			cout << i << " ";
		}cout << endl;
		
		vector<int>::iterator pos = find(v.begin(), v.end(), 3);
		cout << (pos - v.begin()) << endl;

		//在pos--3的之前插入
		v.insert(pos, 30);

		cout << v.size() << " " << v.capacity() << endl;
		for (auto& i : v) {
			cout << i << " ";
		}cout << endl;

		cout << (pos - v.begin()) << endl;
		cout << (*pos) << endl;
		//insert以后,pos就是失效了
		//1.pos指向的位置的意义变了,pos不是指向3
		//2.pos成了野指针

	}

	void test_vector5() {
		vector<int>v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5);
		vector<int>::iterator it = v.begin();
		while (it != v.end())
		{
			if (*it % 2 == 0) {
				v.erase(it);
			}
			else ++it;
		}

		cout << v.size() << " " << v.capacity() << endl;
		for (auto i : v) {
			cout << i << " ";
		}cout << endl;
	}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值