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());
}
在实现的过程中存在着迭代器失效的问题。迭代器失效是因为在执行删除或插入操作时,在将旧有的数据拷贝到新开辟的空间中,插入或删除数据后,撤销旧的内存空间,造成的指针失效的问题。
具体情况如下:
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();
}