阅读本文需要对顺序表有一定的了解,欢迎您的阅读。
首先介绍模板函数:顾名思义,就是一个模板让别的事物套用的,c++中的模板就是同一结构的不同类型套用的,举个简单例子,要使用这个结构的模板,int可以用,char也可以用,等等
好了不罗嗦了,直接上实现函数吧!
模板结构如下:
template<typename T> //模板函数,T为参数类型
class SeqList
{
public:
SeqList();
SeqList(T *array, size_t size);
SeqList(const SeqList &s); //现代写法
SeqList &operator=(SeqList s);
~SeqList();
void PushBack(const T& x); //尾增
void PopBack(); //尾删
void PushFount(const T& x); //头增
void PopFount(); //头删
void Insert(size_t pos, const T& x); //中间插入
void Erase(size_t pos); //中间删除
int Find(T x); //寻找
void PrintSeqList(); //输出
void _CheekCapacity(); //检查容量
private:
T *_array;
size_t _size;
size_t _capaci;
};
构造函数、赋值运算符重载函数:
template<typename T>
SeqList<T>::SeqList()
:_array(NULL),
_size(0),
_capaci(0)
{}
template<typename T>
SeqList<T>::SeqList(T *array, size_t size)
: _array(new T[size]),
_size(size),
_capaci(size)
{
//memcpy(_array, array, sizeof(T)*size); //当T为非基本类型时不能用memcpy
for (size_t i = 0; i < size; i++)
{
_array[i] = array[i];
}
}
//template<typename T>
//SeqList<T>::SeqList(const SeqList& s) //传统写法
// :_array(new T[s._size]),
// _size(s._size),
// _capaci(s._size)
//{
// //memcpy(_array, s._array, sizeof(T)*_size);
// for (size_t i = 0; i < size; i++)
// {
// _array[i] = array[i];
// }
//}
template<typename T>
SeqList<T>::SeqList(const SeqList &s) //现代写法
:_array(NULL)
{
SeqList temp(s._array, s._size);
swap(_array, temp._array);
_size = s._size;
_capaci = s._capaci;
}
template<typename T>
SeqList<T>& SeqList<T>::operator=(SeqList s)
{
swap(s._array, _array);
_size = s._size;
_capaci = s._capaci;
//swap(_size,s._size);
//swap(_capaci,s._capaci);
return *this;
}
//template<typename T>
//SeqList<T>& SeqList<T>::operator=(const SeqList s)
//{
// if (this != &s)
// {
// T *temp = new T[s._size];
// delete[]_array;
// _array = temp;
// _size = s._size;
// _capaci = s._size;
// for (size_t i = 0; i < _size; i++)
// temp[i] = _array[i];
// }
// return *this;
//}
析构函数:
template<typename T>
SeqList<T>::~SeqList()
{
if (_array)
{
delete[] _array;
}
}
插入删除函数:
template<typename T>
void SeqList<T>::PushBack(const T& x)
{
_CheekCapacity();
_array[_size] = x;
_size++;
}
template<typename T>
void SeqList<T>::PopBack()
{
if (_size > 0)
{
_size--;
}
}
template<typename T>
void SeqList<T>::PushFount(const T& x)
{
_CheekCapacity();
for (int i = _size; i > 0; i--)
{
_array[i] = _array[i - 1];
}
_array[0] = x;
_size++;
}
template<typename T>
void SeqList<T>::PopFount()
{
if (_size == 0)
{
cout << "空链表" << endl;
}
for (size_t i = 0; i < _size - 1; i++)
{
_array[i] = _array[i + 1];
}
_size--;
}
template<typename T>
void SeqList<T>::Insert(size_t pos, const T& x)
{
_CheekCapacity();
if (pos<_size)
for (int i = _size; i > _size - pos; i--)
{
_array[i] = _array[i - 1];
}
_array[pos - 1] = x;
_size++;
}
template<typename T>
void SeqList<T>::Erase(size_t pos)
{
if (_size == 0)
{
cout << "空链表,无需删除!" << endl;
}
for (int i = pos; i < _size; i++)
{
_array[i - 1] = _array[i];
}
_size--;
}
寻找值的函数、输出内容函数:
template<typename T>
int SeqList<T>::Find(T x)
{
if (_size == 0)
{
cout << "空链表!" << endl;
}
for (int i = 0; i < _size; i++)
{
if (x == _array[i])
{
return i + 1;
}
}
return -1;
}
template<typename T>
void SeqList<T>::PrintSeqList()
{
for (int i = 0; i < (int)_size; i++)
cout << _array[i] << " ";
cout << endl;
}
检查容量和增容函数:
template<typename T>
void SeqList<T>::_CheekCapacity()
{
if (_size >= _capaci)
{
_capaci = 2 * _capaci + 3;
T* temp = new T[_capaci];
for (size_t i = 0; i < _size; i++)
temp[i] = _array[i];
swap(_array, temp);
}
}
上述代码全部定义于我自定义的typetemp.h头文件中,并写在#ifndef _TYPETEMP_H__ #define _TYPETEMP_H__ 和 #endif之间
测试函数如下:
#include"SeqList.h"
void test2()
{
cout << "使用 int 类型构造 :" << endl;
cout << "s1:" << endl;
SeqList<int> s1;
s1.PushBack(1);
s1.PushBack(2);
s1.PushBack(3);
s1.PushBack(4);
s1.PushBack(5);
s1.PrintSeqList();
cout << "s2:" << endl;
SeqList<int> s2(s1);
s2.PopBack();
s2.PrintSeqList();
cout << "s3:" << endl;
SeqList<int> s3;
s3 = s1;
s3.PopFount();
s3.PrintSeqList();
}
void test3()
{
cout << "使用 char 类型构造 :" << endl;
cout << "s1:" << endl;
SeqList<char> s1;
s1.PushBack('a');
s1.PushBack('b');
s1.PushBack('c');
s1.PushBack('d');
s1.PushBack('e');
s1.PrintSeqList();
cout << "s2:" << endl;
SeqList<char> s2(s1);
s2.PopBack();
s2.PrintSeqList();
cout << "s3:" << endl;
SeqList<char> s3;
s3 = s1;
s3.PopFount();
s3.PrintSeqList();
}
void test4()
{
cout << "使用 string 类型构造 :" << endl;
cout << "s1:" << endl;
SeqList<string> s1;
s1.PushBack("xxxx");
s1.PushBack("ssss");
s1.PushBack("aaaa");
s1.PushBack("dddd");
s1.PushBack("eeee");
s1.PrintSeqList();
cout << "s2:" << endl;
SeqList<string> s2(s1);
s2.PopBack();
s2.PrintSeqList();
cout << "s3:" << endl;
SeqList<string> s3;
s3 = s1;
s3.PopFount();
s3.PrintSeqList();
}
int main()
{
test2();
test3();
test4();
system("pause");
return 0;
}
运行函数,查看结果:
注意事项:当使用基本类型,如int char float 等类型时,模板函数可以用memcpy,realloc 等涉及内存的函数;当时用非基本类型,如string 类型时,模板函数不能使用memcpy等涉及内存操作的函数,因为会产生程序崩溃等现象,原因是由于调用析构函数引起的,这里就不详加讨论,这篇文章里的函数都没有使用memcpy 等函数,这样函数还不是最优化的,优化方案我会在下一篇博客 <模板函数-类型萃取>里边解决,欢迎阅读,谢谢!
限于我目前的c++水平 仅能实现上述函数,欢迎大家阅读,如发现错误或者不足,恳请您给予批评指正,谢谢!
本文出自 “分享中进步” 博客,请务必保留此出处http://xmwen1.blog.51cto.com/10730069/1751962