您的位置:首页 > 其它

模拟实现vector(迭代器,类型萃取)

2017-10-23 23:01 501 查看
vector是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++函数重载,以及模板特化来完成类型萃取。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: