类型萃取实现vector
2017-06-26 21:16
288 查看
C++中通过类型萃取来实现对象类型的识别。
类型萃取的实际用例:1.SeqList 2.统一内存管理 3.STL
POD:plain old data平凡类型--基本类型,值C++中与C兼容的类型,可以按照C的方式处理
POD类型萃取如下:
vector顾名思义,是C++中的容器,用以实现对一组数据执行一些操作,如:插入,删除,查找,遍历等,可以用于C++中的任意数据类型,在模拟实现Vector时需要用到上述提到的类型萃取方法,用以识别在使用中对数据类型的识别。
在实现的过程中存在着迭代器失效的问题。迭代器失效是因为在执行删除或插入操作时,在将旧有的数据拷贝到新开辟的空间中,插入或删除数据后,撤销旧的内存空间,造成的指针失效的问题。
具体情况如下:
1.当插入(push_back)一个元素后,end操作返回的迭代器肯定失效。
2.当插入(push_back)一个元素后,capacity返回值与没有插入元素之前相比有改变,则需要重新加载整个容器,此时first和end操作返回的迭代器都会失效。
3.当进行删除操作(erase,pop_back)后,指向删除点的迭代器全部失效;指向删除点后面的元素的迭代器也将全部失效。
Vector实现代码如下:
类型萃取的实际用例: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(); }
相关文章推荐
- C++实现Vector->类型萃取和List->迭代器
- 模拟实现容器vector(含迭代器、类型萃取)
- 模拟实现vector(迭代器,类型萃取)
- STL-模拟实现vector(含类型萃取)
- 自己实现vector,对于自定义类型可用,可以实现vector的嵌套。功能上目前只实现了插入和删除。
- C++之STL(三):迭代器类vector::iterator 和 vector::reverse_iterator 的实现、迭代器类型、常用的容器成员
- find_if和函数对象结合实现对自定义类型vector的查找 复杂结构体查询某个值
- 从零开始学C++之STL(三):迭代器类vector::iterator 和 vector::reverse_iterator 的实现、迭代器类型、常用的容器成员
- 【干货】C++通过模板特化实现类型萃取实例--实现区分基本类型与自定义类型的memcpy
- 【C++】类型萃取技术实现静态顺序表
- 迭代器类vector::iterator 和 vector::reverse_iterator 的实现、迭代器类型、常用的容器成员
- find_if和函数对象结合实现对自定义类型vector的查找
- 【代码】模板实现动态线性表(无类型萃取)
- 【C++】类型萃取技术实现静态顺序表
- find_if和函数对象结合实现对自定义类型vector的查找
- 通过模板的特化实现 简单的类型萃取 实现memcppy时候对于特殊类型如string类的拷贝。
- 通过模板的特化实现 简单的类型萃取 实现memcppy时候对于特殊类型如string类的拷贝。
- 从零开始学C++之STL(三):迭代器类vector::iterator 和 vector::reverse_iterator 的实现、迭代器类型、常用的容器成员
- 【干货】C++通过模板特化实现类型萃取实例--实现区分基本类型与自定义类型的memcpy
- 【代码】模板实现动态线性表(无类型萃取)