11. 函数模板类模板实现vector顺序容器空间适配器
Posted 为了财务自由!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了11. 函数模板类模板实现vector顺序容器空间适配器相关的知识,希望对你有一定的参考价值。
// 模板的声明
template<typename T>
bool compare(T a, T b)
return a>b;
int main()
compare<int>(20,30);
//模板的实参推演!
compare(20,30);
编译器优先把函数名看成普通函数,找不到的话,才考虑是个函数模板!:
compare (“aaa”,“bbb”);
模板不能分开文件定义(一个文件定义,一个文件使用)!因为编译产生符号,链接时找不到符号,出现错误!所以模板代码一般放在头文件.h中定义!那我如果就是要分开在另一个cpp文件定义怎么办呢?
在另一个cpp文件处写好可能的实例化类型:类似于
template bool compare(int,int);
template bool compare(double,double);
类模板
//实现栈容器
template<typename T>
class SeqStack //模板名称+类型参数列表=类名称
public:
//构造和析构函数名不用加<T>,其他出现模板的地方需要加上类型参数列表
SeqQueue(int size=10)
:_pstack(new T[size])
,_top(0)
,_size(size)
~SeqQueue()
delete[] _pstack;
_pstack=nullptr;
SeqQueue(const SeqQueue<T>& stack)
:_top(stack._top)
,_size(stack._size)
_pstack = new T[_size];
//不要用memcpy进行拷贝(是个对象就不能用)
for(int i=0;i<_top;++i)
_pstack[i] = stack._pstack[i];
SeqStack<T>& operqtor=(const SeqStack<T>& stack)
if(this == &syack)
return *this;
delete[] _pstack;
_top=stack._top;
_size=stack._size;
_pstack=new T[_size];
for(int i=0;i<_top;++i)
_pstack[i] = stack._pstack[i];
void push(const T& val)
if(full())
expand();
_pstack[top++]=val;
void pop()
if(empty())
return;
--_top;
T top() const
if(empty())
throw "stack is empty!";
return _pstack[top-1];
bool full() const
return _top == _size;
bool empty() const
return _top == 0;
private:
T* _pstack;
int _size;
int _top;
//顺序栈底层数组2倍方式扩容
void expand()
T* ptmp = new T[_size*2];
for(int i=0;i<_top;++i)
ptmp[i] = _pstack[i];
delete[] _pstack;
_pstack = ptmp;
_size *= 2;
;
//vector
template<typename T>
public:
vector(int size=10)
_first=new T[size];
_last=_first;
_end=_first+size;
~vector()
delete[] _first;
_first = _last = _end = nullptr;
vector(const vector<T>& rhs)
int size=rhs._end - rhs._first;
_first=new T[size];
int len = rhs._last - rhs._first;
for(int i=0;i<len;++i)
_first[i] = rhs._first[i];
_last = _first+len;
_end = _first+size;
vector<T>& operator= (const vector<T>& rhs)
if(this == &rhs)
return ;
delete[] _first;
int size = rhs._end - rhs._first;
_first=new T[size];
int len = rhs._last - rhs._first;
for(int i=0;i<len;++i)
_first[i] = rhs._first[i];
_last = _first+len;
_end = _first+size;
return *this;
void push_back(T& val)
if(full())
expand();
*_last=val;
_last++;
void pop_back()
if(empty())
return ;
--_last;
//返回容器末尾的值
T back()const
return *(_last-1);
bool full()const
return _last == _end;
bool empty()const
return _first == _last;
int size()const
return _last - _first;
private:
T* _first;//指向数组起始位置
T* _last;//指向数组中有效元素的后继位置
T* _end;//指向数组空间的后继位置
void expand()//2倍扩容
int size = _end - _first;
T* ptmp = new T[2*size];
for(int i=0;i<size;i++)
ptmp[i] = _first[i];
delete[] _first;
_first = ptmp;
_last = _fist + size;
_end = _first + size*2;
以上代码缺少空间适配器!
class Test
public:
Test()cout << "Test()" << endl;
~Test()cout << "~Test()" << endl;
;
//这回出现很多次构造与析构!因为自实现的vector内部实现是new出来的空间
//但是我们此时认为这个容器是空的,但是实际上已经默认有size个对象了!不合理!
vector<Test> vec;
//那么在pop_back时,内部实现是实现指针的移动就搞定了,这会造成对象内存没有释放!
//我们需要改进,pop_back时需要释放内存!
引入空间适配器!
allocator做四件事情:内存开辟/内存释放、对象构造/对象析构
template<typename T>
struct Allocator
//负责内存开辟
T* allocate(size_t size)
return (T*)malloc(sizeof(T)*size);
//负责内存释放!
void deallocate(void* p)
free(p);
//负责对象构造!
void construct(T* p,const T&val)
new(p) T(val);//定位new,在指定的地址(p)存放val
void destroy(T* p)
p->~T();//~T()代表T类型析构函数
;
把上面的vector代码改进:
//vector
template<typename T,typename Alloc = Allocator<T>>
public:
vector(int size=10,const Alloc& alloc = Allocator<T>())
:_allocator(alloc)
//_first=new T[size];
_first = _allocator.allocate(size);
_last=_first;
_end=_first+size;
//析构容器有效个数的元素,然后释放_first指针指向的堆内存
~vector()
//delete[] _first;
for(T* p=_first;p!=_last;++p)
//把_first指针指向的数组有效元素进行析构操作
_allocator.destory(p);
_allocator.deallocate(_first);
_first = _last = _end = nullptr;
vector(const vector<T>& rhs)
int size=rhs._end - rhs._first;
//_first=new T[size];
_first = _allocator.allocate(size);
int len = rhs._last - rhs._first;
for(int i=0;i<len;++i)
//_first[i] = rhs._first[i];
_allocator.construct(_first+i,rhs._first[i]);
_last = _first+len;
_end = _first+size;
vector<T>& operator= (const vector<T>& rhs)
if(this == &rhs)
return ;
//delete[] _first;
for(T* p=_first;p!=_last;++p)
//把_first指针指向的数组有效元素进行析构操作
_allocator.destory(p);
_allocator.deallocate(_first);
int size=rhs._end - rhs._first;
//_first=new T[size];
_first = _allocator.allocate(size);
int len = rhs._last - rhs._first;
for(int i=0;i<len;++i)
//_first[i] = rhs._first[i];
_allocator.construct(_first+i,rhs._first[i]);
_last = _first+len;
_end = _first+size;
return *this;
void push_back(T& val)
if(full())
expand();
//*_last=val;
//_last++;
_allocator.construct(_last,val);
_last++;
void pop_back()
if(empty())
return ;
--_last;
_allocator.destroy(_last);
//返回容器末尾的值
T back()const
return *(_last-1);
bool full()const
return _last == _end;
bool empty()const
return _first == _last;
int size()const
return _last - _first;
private:
T* _first;//指向数组起始位置
T* _last;//指向数组中有效元素的后继位置
T* _end;//指向数组空间的后继位置
Alloc _allocator;//定义容器的空间适配器对象!
void expand()//2倍扩容
int size = _end - _first;
//T* ptmp = new T[2*size];
T* ptmp = _allocator.allocate(2*size);
for(int i=0;i<size;i++)
//ptmp[i] = _first[i];
_allocator.construct(ptmp+i,_first[i]);
//delete[] _first;
for(T* p=_first;p!=_last;++p)
_allocator.destroy(p);
_allocator.deallocate(_first)
_first = ptmp;
_last = _fist + size;
_end = _first + size*2;
以上是关于11. 函数模板类模板实现vector顺序容器空间适配器的主要内容,如果未能解决你的问题,请参考以下文章
用类模板实现容器存储自定义数据类型(类似于STL里面的vector)