模拟实现vector(迭代器,类型萃取)
2017-10-23 23:01
501 查看
vector是C++标准库中的部分内容,是一个多功能,能够操作多种数据机构和算法的模板类和函数库。
vector被认为是一个容器,是因为它能像容器一样存放各种类型的对象,能够存放任意类型的动态数组,能够增加和压缩数据。
适合用顺序表实现:
其中:
相当于函数的重载,根据传的参数不同调用不同的函数。
其中
是模板类,以及特化。
如果T是内置类型,那么IsPOD将会是TrueType的别名,否则IsPOD将会是FalseType的别名。
那么此时IsPOD的类型将影响到函数的调用
假设此时T的类型是 int
使用类型萃取是因为,如果内置类型中有指针数据,如果使用与内置类型相同的memcpy,在对象生命周期结束时,会出现多次释放同一空间的问题,导致程序崩溃。
同样的也可以换一种方法:
将上面的一些地方进行修改
调用过程:
利用C++函数重载,以及模板特化来完成类型萃取。
vector被认为是一个容器,是因为它能像容器一样存放各种类型的对象,能够存放任意类型的动态数组,能够增加和压缩数据。
适合用顺序表实现:
#include<assert.h> #include<iostream> using namespace std; struct TrueType {}; struct FalseType {}; template <typename T> struct TypePOD { typedef FalseType IsPOD; }; template<> struct TypePOD<int> { typedef TrueType IsPOD; }; template<> struct TypePOD<char> { typedef TrueType IsPOD; }; template<> struct TypePOD<double> { typedef TrueType IsPOD; }; template<> struct TypePOD<long> { typedef TrueType IsPOD; }; template<> struct TypePOD<float> { typedef TrueType IsPOD; }; template<class T> class Iterator; template<class T> class Vector { public: typedef Iterator<T> Iterator; 4000 // 成员函数 Vector() //构造函数 :_start(0), _finish(0), _endOfStorage(0) {} Vector(const T* array, size_t size) //数组传参 :_start(new T[size]), _finish(_start + size), _capacity(_start + size) { for (size_t i = 0; i < size; i++) { _start[i] = array[i]; } } //拷贝构造函数 Vector(const Vector &v) { size_t size = v.Size(); _start = new T[size]; _Fun(_start,v._start,size,TypePOD<T>::IsPOD()); _finish = _start + size; _endOfStorage = _finish; } Vector& operator=(const Vector &s)//赋值运算符的重载 { size_t size = s.Size(); if (this != &s) //判同 { T *tmp = new T[size]; _Fun(_start, v._start, size, TypePOD<T>::IsPOD()); delete[] _start; _start = tmp; _finish = _start + size; _endOfStorage = _finish; } return *this; } //析构函数 ~Vector() { if (_start != NULL) { delete[] _start; _start = NULL; } } ///////////////itreator///////////////// Iterator Begin() { return Iterator(this->_start); } Iterator End() { return Iterator(this->_finish); } public: ///////////////////Modify//////////////////////////////// void PushBack(const T& data) //尾插 { _CheckCapacity(); *_finish = data; _finish++; } void PopBack() //尾删 { assert(_start < _finish); _finish--; } void Insert(size_t pos, const T& data) //指定位置插入 { assert(pos <= Size()); _CheckCapacity(); for (size_t i = Size(); i >= pos; i--) { _start[i] = _start[i - 1]; } _start[pos - 1] = data; _finish++; } void Erase(size_t pos) //指定位置删除 { assert(pos <= Size()); for (size_t i = pos - 1; i < Size(); i++) { _start[i] = _start[i + 1]; } _finish--; } //////////////////capacity//////////////////////////// size_t Size()const //元素个数 { return _finish - _start; } size_t Capacity()const //顺序表容量 { return _endOfStorage - _start; } bool Empty()const //判断是否为空 { if (_start == _finish) { return true; } return false; } void Resize(size_t newSize, const T& data = T()) //改变顺序表大小 { size_t oldsize = Size(); size_t capacity = Capacity(); if (newSize <= oldsize) { _finish = _start + newSize; } else if ((newSize > oldsize) && (newSize <= capacity)) { for (size_t i = oldsize; i < newSize; i++) { *_finish++ = data; } } else { T *tmp = new T[newSize]; for (size_t i = 0; i < oldsize; i++) tmp[i] = _start[i]; for (size_t i = oldsize; i < newSize; i++) tmp[i] = data; delete[] _start; _start = tmp; _finish = _start + newSize; _endOfStorage = _finish; } } ////////////////Acess/////////////////////////// T& operator[](size_t index) //重载访问符[] { assert(index <= Capacity()); return _start[index]; } const T& operator[](size_t index)const // const重载访问符[] { assert(index <= Capacity()); return _start[index]; } T& Front() //首元素 { return *_start; } const T& Front()const // const 返回头部元素 { return *_start; } T& Back() //返回尾部元素 { return *(_finish - 1); } const T& Back()const { return *(_finish - 1); } void Clear() //清空顺序表 { _finish = _start; } //输出运算符重载 template<class T> friend ostream& operator<<(ostream& _cout, const Vector<T>& v) //声明为友元 { for (size_t i = 0; i < v.Size(); i++) _cout << v._start[i] << " "; cout << endl; return _cout; } private: void _CheckCapacity() //分配内存 { size_t size = Size(); size_t OldCapacity = Capacity(); size_t NewCapacity = 2 * OldCapacity + 3; if (size >= OldCapacity) { T *tmp = new T[NewCapacity]; _Fun(tmp, _start, size, TypePOD<T>::IsPOD()); delete[] _start; _start = tmp; _finish = _start + size; _endOfStorage = _start + NewCapacity; } } private: void _Fun(T*dest,const T*src, size_t size, struct TrueType) //内置类型 { memcpy(dest, src, sizeof(T)*size); } void _Fun(T *dest,const T*src, size_t size, struct FalseType) //自定义类型 { for (size_t i = 0; i < size; i++) { dest[i] = src[i]; } } protected: T* _start; T* _finish; T* _endOfStorage; }; template<class T> class Iterator //迭代器 { public: typedef Vector<T> Node; typedef Iterator<T> Self; //T public: Iterator(Node *node) :_node(node) {} T& operator *() { // * 操作符重载 return _node->_start; } T* operator->() { // -> 操作符重载 return &(_node->_start); } Self operator++() { // 前置 ++ 操作符重载 _node->_start++; return *this; } Self operator++(int) //后置 ++ 操作符重载 { Self temp = _node; _node->_start++; return Self(temp); } Self operator--() { //前置 -- 操作符重载 _node->_start--; return *this; } Self operator--(int) { //后置 -- 操作符重载 Self temp = _node; _node->_start--; return Self(temp); } bool operator!=(const Self& s) const { return this->_node != s._node; } bool operator==(const Self& s) const { return this->_node == s._node; } private: Node *_node; };
其中:
void _Fun(T*dest,const T*src, size_t size, struct TrueType) //内置类型 { memcpy(dest, src, sizeof(T)*size); } void _Fun(T *dest,const T*src, size_t size, struct FalseType) //自定义类型 { for (size_t i = 0; i < size; i++) { dest[i] = src[i]; } }
相当于函数的重载,根据传的参数不同调用不同的函数。
其中
template <typename T> struct TypePOD { typedef FalseType IsPOD; }; template<> struct TypePOD<int> { typedef TrueType IsPOD; }; template<> struct TypePOD<char> { typedef TrueType IsPOD; }; template<> struct TypePOD<double> { typedef TrueType IsPOD; }; template<> struct TypePOD<long> { typedef TrueType IsPOD; }; template<> struct TypePOD<float> { typedef TrueType IsPOD; };
是模板类,以及特化。
如果T是内置类型,那么IsPOD将会是TrueType的别名,否则IsPOD将会是FalseType的别名。
那么此时IsPOD的类型将影响到函数的调用
_Fun(tmp, _start, size, TypePOD<T>: a304 :IsPOD());
假设此时T的类型是 int
//那么调用函数_Fun()将会变为 _Fun(tmp,_start,size,TypePOD<int>::IsPOD()); //而我们已经将 TypePOD<int>特化出来,此时的IsPOD将会是TrueType的别名,所以将会调用 void _Fun(T *dest,const T*src, size_t size, struct FalseType) //内置类型
使用类型萃取是因为,如果内置类型中有指针数据,如果使用与内置类型相同的memcpy,在对象生命周期结束时,会出现多次释放同一空间的问题,导致程序崩溃。
同样的也可以换一种方法:
将上面的一些地方进行修改
struct TrueType { bool Pod() { return true; } }; struct FalseType { bool Pod() { return false; } }; Vector(const Vector &v) { size_t size = v.Size(); _start = new T[size]; _Fun(_start,v._start,size,TypePOD<T>::IsPOD()); if (TypePOD<T>::IsPOD().Pod()) { memcpy(dest, src, sizeof(T)*size); } else { for (size_t i = 0; i < size; i++) { dest[i] = src[i]; } } _finish = _start + size; _endOfStorage = _finish; }
调用过程:
利用C++函数重载,以及模板特化来完成类型萃取。
相关文章推荐
- 模拟实现容器vector(含迭代器、类型萃取)
- STL-模拟实现vector(含类型萃取)
- C++实现Vector->类型萃取和List->迭代器
- C++之STL(三):迭代器类vector::iterator 和 vector::reverse_iterator 的实现、迭代器类型、常用的容器成员
- 迭代器类vector::iterator 和 vector::reverse_iterator 的实现、迭代器类型、常用的容器成员
- 类型萃取实现vector
- 从零开始学C++之STL(三):迭代器类vector::iterator 和 vector::reverse_iterator 的实现、迭代器类型、常用的容器成员
- 从零开始学C++之STL(三):迭代器类vector::iterator 和 vector::reverse_iterator 的实现、迭代器类型、常用的容器成员
- STL库中的vector的使用和模拟实现
- [置顶] 从零开始学C++之对象语义与值语义、资源管理(RAII、资源所有权)、模拟实现auto_ptr<class>、实现Ptr_vector .
- <STL>模拟实现Vector
- java中模拟迭代器实现迭代数组
- 模拟实现qsort, qsort对多类型数据进行排序
- MFC中RTTI 运行时类型识别 的模拟实现
- 标准库vector类型和迭代器iterator类型
- 【STL】迭代器与List的模拟实现
- C++模拟实现Objective-C动态类型(附源码)
- Counting-out Rhyme<vector实现约瑟夫环模拟>
- 【STL】模拟实现vector
- 《c++ primer》——2 标准库vector类型和迭代器iterator