您的位置:首页 > 编程语言 > C语言/C++

类型萃取实现vector

2017-06-26 21:16 288 查看
C++中通过类型萃取来实现对象类型的识别。

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

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

POD类型萃取如下:

#pragma once

struct _TrueType
{};
struct _FlaseType
{};

template <class T>
struct TypeTraits
{
typedef _FlaseType IsPodType;
};
template <>
struct TypeTraits<int>
{
typedef _TrueType IsPodType;
};
template <>
struct TypeTraits<char>
{
typedef _TrueType IsPodType;
};
template <>
struct TypeTraits<double>
{
typedef _TrueType IsPodType;
};
template<>
struct TypeTraits<float>
{
typedef _TrueType IsPodType;
};
template <class T>
struct TypeTraits<T*>
{
typedef _TrueType IsPodType;
};

template <class T>
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 <class T>
T* _Copy(T* dst, T* src, size_t n, _TrueType)
{
memcpy(dst, src, n*sizeof(T));
return dst;
}
template <class T>
T* Copy(T* dst,T* src,size_t n)				//模拟拷贝函数
{
return _Copy(dst, src, n, TypeTraits<T>::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 T>
class Vector
{
public:
typedef T* Iterator;
typedef const T* ConstIterator;
Vector()
: _start(0)
, _finsh(0)
, _endStorage(0)
{}
Vector(const Vector<T>& 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
;
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<int> 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<int> v;
v.PushBack(1);
v.PushBack(2);
v.PushBack(3);							//尾插测试
v.PushBack(4);
v.PushBack(5);
v.Print();

//Vector<int>::Iterator it=v.Find(3);  //测试查找函数
//cout << *it << endl;
//Vector<int>::Iterator it2 = v.Find(6);  //测试查找函数
//cout << it2 << endl;
Vector<int>::Iterator pos = v.Find(3);
v.Insert(pos, 6);			//插入测试
v.Print();
//Vector<int>::Iterator pos2 = v.Find(3);
//v.Erase(pos2);				//测试任意位置删除
//v.Print();
//Vector<int>::Iterator pos2 = v.Find(1);
//v.Erase(pos2);				//测试任意位置删除,删头部
//v.Print();
//Vector<int>::Iterator pos2 = v.Find(5);
//v.Erase(pos2);				//测试任意位置删除
//v.Print();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  class struct c语言
相关文章推荐