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;
// 成员函数
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>::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++函数重载,以及模板特化来完成类型萃取。