一.模板
模板就是实现与类型无关的代码,增加了代码的复用性。模板分为模板函数和模板类
模板函数的格式 typedef<calss形参名1 ,class 形参名2 >
返回类型 函数名 参数列表
class也可以用typename,意义相同。
{...}
二.模板类
浅拷贝
当需要数据大于所给定的数据时这时我们会考虑增容。
void Vector <T>::_CheckCapacity()
{
size_t newcapacity = 0;
if (_size >= _capacity)
{
size_t newcapacity = _capacity * 2 + 2;
T*tmp = new T[newcapacity];
memcpy(tmp, _data, sizeof(T)*_size);
delete[]_data;
_data = tmp;
_capacity = newcapacity;
}
}
void test()
{
Vector<int>v1;//int
v1.PushBack(1);
v1.PushBack(2);
v1.PushBack(2);
v1.PushBack(3);
v1.Print();
Vector <string> v3;
v3.PushBack("v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1");
v3.PushBack("v2");
v3.PushBack("v3");
v3.PushBack("v4");
v3.Print();
}
我们再看下监视窗口:
我们再画出对象模型来分析:
当数据缓冲区的数据小于15时,直接拷贝数据,不会出先野指针的问题,当数据缓冲区的数据大于15时,这是就会在堆上开辟空间,有两个ptr指针指向这同一块空间,调用memcpy拷贝数据后,当调用delete函数时会调用析构函数,释放s1,此时ptr2也指向这块空间,此时ptr2就是一个野指针,这时候就会出先内存泄露的问题。
要怎么解决呢?这时我们会想到深拷贝:
深拷贝
template <typename T>
void Vector <T>::_CheckCapacity()
{
size_t newcapacity = 0;
if (_size >= _capacity)
{
size_t newcapacity = _capacity * 2 + 2;
T*tmp = new T[newcapacity];
for (size_t i = 0; i < _size; ++i)
{
tmp[i] = _data[i];
}
delete[]_data;
_data = tmp;
_capacity = newcapacity;
}
顺序表的模板实现:
#include<iostream>
#include<string>
#include<assert.h>
using namespace std;
template <typename T>
class Vector
{
public:
Vector();
Vector(const Vector&v);
Vector &operator =(const Vector&v);
~Vector();
public:
void Print();
void PushBack(const T&x);
void PopBack();
void PushFront(const T&x);
void PopFront();
void Insert(size_t pos,const T&x);
void Erase(size_t pos);
protected:
void Swap();
void _CheckCapacity();
protected:
T* _data;
size_t _size;
size_t _capacity;
};
//构造
template <typename T>
Vector <T> ::Vector()
:_data(NULL)
,_size(0)
,_capacity(0)
{}
//拷贝构造 s2(s1)
template <typename T>
Vector <T>::Vector(const Vector&v)
{
_data = new T[v._capacity];
for (size_t i = 0; i < _size; ++i)
{
_data = v._data;
}
_size = v._size;
_capacity = v._capacity;
}
//赋值运算符的重载s3 = s1;
template <typename T>
Vector<T> &Vector <T>::operator =(const Vector& v)
{
if (*this != &v)
{
T*tmp = new T[v._size];
for (size_t i = 0; i < _size; ++i)
{
tmp[i] = v._data[i];
}
delete[]_data;
_data = tmp;
_size = _v._size;
_capacity = v._capacity;
}
return *this;
}
template <typename T>
Vector <T>::~Vector()
{
if (_data)
{
delete[]_data;
_data = NULL;
_size = _capacity = 0;
}
}
template <typename T>
void Vector <T>:: Print()
{
for (size_t i = 0; i < _size; ++i)
{
cout << _data[i] << " ";
}
cout << endl;
}
template <typename T>
void Vector <T>::_CheckCapacity()
{
size_t newcapacity = 0;
if (_size >= _capacity)
{
size_t newcapacity = _capacity * 2 + 2;
T*tmp = new T[newcapacity];
for (size_t i = 0; i < _size; ++i)
{
tmp[i] = _data[i];
}
delete[]_data;
_data = tmp;
_capacity = newcapacity;
}
}
//尾插
template <typename T>
void Vector <T>::PushBack(const T& x)
{
_CheckCapacity();
_data[_size++] = x;
}
//尾删
template <typename T>
void Vector <T>::PopBack()
{
assert(_size > 0);
_data[--_size] = '\0';
}
//头插
template <typename T>
void Vector <T>::PushFront(const T& x)
{
_CheckCapacity();
for (size_t i = _size; i>0; --i)
{
_data[i] = _data[i-1];
}
_data[0] = x;
++_size;
}
//头删
template <typename T>
void Vector <T>::PopFront()
{
assert(_size > 0);
for (size_t i = 0; i < _size; --i)
{
_data[i] = _data[i + 1];
}
--_size;
}
//在位置上插入数据
template <typename T>
void Vector <T>::Insert(size_t pos, const T&x)
{
_CheckCapacity();
if (pos == 0)
{
PushBack(x);
}
else
{
for (size_t i = pos; i < _size; ++i)
{
_data[i + 1] = _data[i];
}
_data[pos] = x;
++_size;
}
}
//删除某个位置的数据
template <typename T>
void Vector <T>::Erase(size_t pos)
{
assert(pos >= 0 && pos <= _size);
size_t end = _size;
while (end != pos)
{
_data[pos] = _data[pos + 1];
--end;
}
--_size;
}
int main()
{
Vector<int>v1;//int
v1.PushBack(1);
v1.PushBack(2);
v1.PushBack(2);
v1.PushBack(3);
v1.Print();
v1.PopBack();
v1.PopBack();
v1.PopBack();
v1.PopBack();
v1.Print();
v1.PushFront(4);
v1.PushFront(5);
v1.PushFront(6);
v1.PushFront(7);
v1.Print();
v1.PopFront();
v1.PopFront();
v1.PopFront();
v1.PopFront();
v1.Print();
v1.Insert(0, 1);
v1.Insert(1, 2);
v1.Insert(2, 3);
v1.Print();
v1.Erase(1);
v1.Erase(2);
v1.Print();
Vector <string> v2;
v2.PushBack("v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1v1");
v2.PushBack("v2");
v2.PushBack("v3");
v2.PushBack("v4");
v2.Print();
Vector<string> v3;
v3.PushBack("v1");
v3.PushBack("v2");
v3.PushBack("v3");
v3.Print();//char *(隐式类型的转换)
v3.PopBack();
v3.PopBack();
v3.PopBack();
v3.Print();
v3.Erase(0);
v3.Erase(1);
v3.Erase(1);
v3.Print();
system("pause");
return 0;
}