类型萃取实现vector

C++中通过类型萃取来实现对象类型的识别。

类型萃取的实际用例:1.SeqList 2.统一内存管理 3.STL

POD:plain old data平凡类型--基本类型,值C++中与C兼容的类型,可以按照C的方式处理


POD类型萃取如下:

#pragma once

struct _TrueType
{};
struct _FlaseType
{};

template 
struct TypeTraits
{
	typedef _FlaseType IsPodType;
};
template <>
struct TypeTraits
{
	typedef _TrueType IsPodType;
};
template <>
struct TypeTraits
{
	typedef _TrueType IsPodType;
};
template <>
struct TypeTraits
{
	typedef _TrueType IsPodType;
};
template<>
struct TypeTraits
{
	typedef _TrueType IsPodType;
};
template 
struct TypeTraits
{
	typedef _TrueType IsPodType;
};

template 
T* _Copy(T* dst, T* src, size_t n, _FlaseType)
{
	for (size_t i = 0; i < n; i++)
	{
		dst[i] = src[i];
	}
	return dst;
}
template 
T* _Copy(T* dst, T* src, size_t n, _TrueType)
{
	memcpy(dst, src, n*sizeof(T));
	return dst;
}
template       
T* Copy(T* dst,T* src,size_t n)				//模拟拷贝函数
{
	return _Copy(dst, src, n, TypeTraits::IsPodType());
}

vector顾名思义,是C++中的容器,用以实现对一组数据执行一些操作,如:插入,删除,查找,遍历等,可以用于C++中的任意数据类型,在模拟实现Vector时需要用到上述提到的类型萃取方法,用以识别在使用中对数据类型的识别。

在实现的过程中存在着迭代器失效的问题。迭代器失效是因为在执行删除或插入操作时,在将旧有的数据拷贝到新开辟的空间中,插入或删除数据后,撤销旧的内存空间,造成的指针失效的问题。

具体情况如下:  

 1.当插入(push_back)一个元素后,end操作返回的迭代器肯定失效。

 2.当插入(push_back)一个元素后,capacity返回值与没有插入元素之前相比有改变,则需要重新加载整个容器,此时first和end操作返回的迭代器都会失效。

 3.当进行删除操作(erase,pop_back)后,指向删除点的迭代器全部失效;指向删除点后面的元素的迭代器也将全部失效。

Vector实现代码如下:

#pragma once
#include "TypeTraits.h"

using namespace std;

template 
class Vector
{
public:
	typedef T* Iterator;
	typedef const T* ConstIterator;
	Vector()
		: _start(0)
		, _finsh(0)
		, _endStorage(0)
	{}
	Vector(const Vector& v)
		: _strat(0)
		, _finsh(0)
		, _endStorage(0)
	{
		this->_Expend(v.Size());
		Copy(_start, v._start, v.Size);
		_finsh = _start + v.Size();
		_endStorage = _start + v.Size();
	}
	~Vector()   //注意
	{
		if (_start)
		{
			delete[] _start;
			_start = _finsh = _endStorage = NULL;
		}
	}

	void PushBack(const T& v)
	{
		if (_finsh >= _endStorage)
		{
			size_t capacity = Capacity();
			capacity = capacity + capacity / 2;
			if (capacity < Size() + 1)			//验证是否增容成功
				capacity = Size() + 1;

			_Expend(capacity);
		}

		*_finsh = v;
		++_finsh;
	}

	void Resize(size_t n,const T& val=T())		//重新分配大小,原size和capacity都改变,可预置操作数
	{
		if (n > Capacity())
		{
			_Expend(n);
		}
		if (n > Size())
		{
			Iterator pos = finsh; 
			while (pos != (_start + n))
			{
				*pos = val;
				++pos;
			}
		}
		else if (n < Size())
		{
			Iterator npos = _start + n;
			while (npos != _finsh)
			{
				npos->~T();			//析构由npos之后的空间
			}
			_finsh = _start + n;	//有疑问????
		}
	}

	void Reserve(size_t n)		//预留空间,只改变capacity
	{
		_Expend(n);
	}

	void PopBack()			   //存在迭代器失效的问题
	{
		if (_start == NULL)
			return;

		if (_start == _finsh)
		{
			_finsh->~T();		//如果只有一个元素时
		}
		else
		{
			Iterator del = _finsh;
			
			--_finsh;
			del->~T();
		}

	}
	
	Iterator Find(const T& x)		//查找该值是否存在,存在的位置
	{
		Iterator cur = _start; 
		while (cur < _finsh)
		{
			if (*cur == x)
			{
				return cur;
			}
			++cur;
		}

		return NULL;
	}
	void Erase(Iterator pos)					//删除位置上的数据
	{
		Iterator cur = pos;

		if (cur == _finsh)
		{										//尾删
			PopBack();
		}
		else
		{
			while (cur < _finsh)
			{
				*cur = *(cur + 1);						//有当前位置向后移动覆盖前一个值
				++cur;
			}
			--_finsh;								//尾部前移
		}
		
	}
	void Insert(Iterator &pos,const T& x)		//在具体的位置插入数据
	{
		if (pos == NULL)
			return;

		if (_finsh == _endStorage)			//判断插入后容量是否足够,同时也判断是否是插入第一个数
			_Expend(Capacity() + 1);
		
		Iterator cur = pos;
		T tem = *pos;
		T next = x;
		while (cur <= _finsh)
		{
			*cur = next;
			next = tem;
			++cur;
			tem = *cur;
		}
		*(++_finsh) = next;
	}

	inline size_t Capacity()
	{
		return _endStorage - _start;
	}
	inline size_t Size()
	{
		return _finsh - _start;
	}
	Iterator Bigin()
	{
		return _start;
	}
	ConstIterator Begin() const
	{
		return _start;
	}
	Iterator End()
	{
		return _finsh;
	}
	ConstIterator End() const
	{
		return _finsh;
	}
	void _Expend(size_t n)
	{
		if (n < Capacity())
			return;
		size_t size = Size();
		T* tem = new T[n];
		Copy(tem, _start, size);

		delete[] _start;
		_start = tem;
		_finsh = _start + size;
		_endStorage = _start + n;
	}
	T& operator[](size_t index)
	{
		if (index>=Size())
			throw out_of_range("out of range");

		return _start[index];
	}
	void Print()
	{
		for (size_t i = 0; i < Size(); i++)
		{
		cout << _start[i]<< " ";
		}
		cout << endl;
	}

protected:
	Iterator _start;
	Iterator _finsh;
	Iterator _endStorage;
};


void TestVector()
{
	Vector v;
	v.PushBack(1);
	v.PushBack(2);
	v.PushBack(3);		//尾插测试
	v.PushBack(4);
	v.PushBack(5);
	v.Print();

	v.PopBack();
	v.Print();
	v.PopBack();
	v.Print();
	v.PopBack();		//尾删测试
	v.Print();
	v.PopBack();
	v.Print();
	v.PopBack();
	v.Print();
	v.PopBack();
	v.Print();
}

void TestVector2()
{
	Vector v;
	v.PushBack(1);
	v.PushBack(2);
	v.PushBack(3);							//尾插测试
	v.PushBack(4);
	v.PushBack(5);
	v.Print();

	//Vector::Iterator it=v.Find(3);  //测试查找函数
	//cout << *it << endl;
	//Vector::Iterator it2 = v.Find(6);  //测试查找函数
	//cout << it2 << endl;
	Vector::Iterator pos = v.Find(3);
	v.Insert(pos, 6);			//插入测试
	v.Print();
	//Vector::Iterator pos2 = v.Find(3);	
	//v.Erase(pos2);				//测试任意位置删除
	//v.Print();
	//Vector::Iterator pos2 = v.Find(1);
	//v.Erase(pos2);				//测试任意位置删除,删头部
	//v.Print();
	//Vector::Iterator pos2 = v.Find(5);
	//v.Erase(pos2);				//测试任意位置删除
	//v.Print();
}



你可能感兴趣的:(class,struct,c语言,文本)