C++学习------模板

 模板<template>



 本篇博客阐述主要内容有:

 1.模板的定义
 2.模板函数
 3.模板类
 4.C++容器


-----------------------------------------------------


   模板:望文生义,就是一个模子,在C++中提供重用源代码的方法;


   函数的重载,就是解决函数接收不同类型的参数的问题而产生的,但是,我们往往是不愿意这样做的,因为这样的话,等于多写了一份代码,拉长了代码长度,于是,就有了模板的存在,模板只需要你写一份代码就可以实现不同类型数据的复;模板的一般使用方式是: template<class T,...>或者template<typename T,...> 尖括号里的模板参数;


例如下面这个简单的例子<函数模板>: 

#include<iostream>
#include<string>

using namespace std;

template<typename T>
bool Equal(const T& a,const T& b)
{
	return a==b;
}

int main()
{
	cout<<Equal<int>(1,2)<<endl;//注意使用的方式,<传参类型>
	cout<<Equal<int>(1.1,2)<<endl; //错误! 注意模板参数的匹配
	cout<<Equal<string>("aaaaa","aaaaa")<<endl;//不同类型的参数

	system("pause");
	return 0;
}

 这样就实现了不同类型参数的函数调用,那么,模板函数实现的机制是什么呢?


其实,这些事情都是编译器在默默的帮你完成. 






 模板类


 我们知道类的实现也依赖于类成员的基本类型,那么模板是怎样实现类的呢?


 举个简单例子:


#include<iostream>

using namespace std;

template<class T = int>// class 或者 typename 是一样的,类的模板参数可以有默认参数;
class Seqlist
{
	T _data;
	int _size;
	int _capacity;
public:
	Seqlist (const T& data,const int size,const int capacity)
		:_data(data)
		,_size(size)
		,_capacity(capacity );
	{}
};


  写过顺序表的同学都知道,顺序表中的数据类型我们一般写的都是int,或者宏定义一下数据类型,为了方便以后数


据类型的修改,但是其实还是很麻烦的,而我再上面简单的用模板参数实现了顺序表数据成员的定义,这样后面所有


的类型都是T类型的;这样,同学们也可以试着用模板参数实现顺序表和链表;


  模板的能力远不止这样,以后我会写关于类型萃取<模板的特化>的博客也是用的模板,还有已经写过的智能指针中


也用了模板!


  《浅析智能指针一

  《浅析智能指针二

 在C++中有容器这样一个概念,比如我们所知道的栈和队列,我在下面贴出模板参数实现栈和队列的模拟实现:

-------------------------------------------------------------------------------------

 模板参数实现栈

#include<iostream>
#include<string>
#include<cassert>

using namespace std;

template<class T>
class SeqList
{
public:
	SeqList ()
		:_pdata(NULL)
		,_size(0)
		,_capacity(3)
	{
		_pdata = new T[3];
	}
	~SeqList ()
	{
		if(_pdata != NULL)
		{
			delete[] _pdata;
			_size = 0;
			_capacity = 0;
		}
	}

	void Display()
	{
		for(int i = 0; i<_size; i++)
		{
			cout<<_pdata[i]<<" ";
		}
		cout<<endl;
	}

	void PushBack(const T& data);
	void PushFront(const T& data);
	void PopBack();
	void PopFront();
	void Sort();
	int Find(const T& P);
	void Intsert(const int& pos,const T& data);
	void Remove(const T& data);
	void RemoveAll(const T& data);


	T& operator[](int size)
	{
		assert(size<_size);
		assert(size>=0);

		return _pdata[size];
	}
	 
public:
	void CheckCapacity()
	{
		int NewCapacity = _capacity*2 + 3;
		if(_size == _capacity)
		{
			T* tmp = new T[NewCapacity];
			
			for(int i = 0; i<_size; i++)
			{
				tmp[i] = _pdata[i];
			}
			delete[] _pdata;
			_pdata = tmp;
			_capacity = NewCapacity ;

		}
	}

	T* _pdata;
	int _size;
	int _capacity;
};

template<typename T>
int SeqList <T>::Find(const T& data)
{
		int i = 0;

		for(i= 0 ; i < _sz; i++)
		{
			if(_pdata[i] == data)//注意这里的等号,千万别写成赋值等;
				return i;
		}
		return -1;
}

template<typename T>
void SeqList<T>:: PushBack(const T& data)
	{
		CheckCapacity ();
		_pdata[_size] = data;
		_size++;
	}

template<class T>
void SeqList<T>::PushFront(const T& data)
{
	    CheckCapacity();
		int length =  _size;
		while(length)
		{
			_pdata[length]=_pdata[length-1];
			length--;
		}
		_pdata[0] = data;
		_size++;
}

template<typename T>
void SeqList <T>::PopBack ()
{
			if(_size>=1)
		{
			_size-=1;
		}
}

template<typename T>
void SeqList <T>::PopFront()
{
			int len = 0;
		while(len<_size-1)
		{
			_pdata[len] = _pdata[len+1];
			len++;
		}
		_size--;
}

template<typename T>
void SeqList <T>::Intsert(const int& pos, const T& data)
{
		CheckCapacity ();

		int index = Find(pos);
		if(index>=0)
		{
			int length = _size;
		while(length > index)
		{
			_pdata[length]=_pdata[length-1];
			length--;
		}
		_pdata[index] = data;
		_size++;
		}
}

template<typename T>
void SeqList <T>::Remove(const T& data)
{
			int index = Find(data);

		if(index>=0)
		{
		while(index<_size-1)
		{
			_pdata[index] = _pdata[index+1];
			index++;
		 }
		}
		_size--;
}

template<typename T>
void SeqList <T>::RemoveAll (const T& data)
{
		while(Find(data)>=0)
		{
			Remove(data);
		}
}

template<typename T>
void SeqList <T>::Sort ()
{
	for(int i = 0; i<_size-1; i++)
	{
		for(int j = 0; j < _size-i-1; j++)
		{
			if(_pdata[j]<_pdata[j+1])
			{
				T tmp = _pdata [j];
				_pdata [j] = _pdata [j+1];
				_pdata [j+1] = tmp;
			}
		}
	}
}

template<typename T, typename Container>
class Stack
{
public:
	void Push(const T& data)
	{
		_con.PushBack(data);
	}
	T& Top()
	{
		int sz = _con._size - 1;
		return _con._pdata[sz];
	}
	bool Empty()
	{
		return _con._size == 0;
	}
	void Pop()
	{
		_con.PopBack();
	}
	void Display()
	{
		while(!Empty())
		{
			cout<<Top()<<"  ";
			Pop();
		}
	}
private:
	Container _con;
};

void test()
{
	SeqList<string> s;
	SeqList<int> s1;
	s1.PushBack(2);
	s1.PushBack(5);
	s1.PushBack(4);
	s1.PushBack(6);
	s.PushBack ("aaaaaaaaaaaaaa");
	s.PushBack ("dsadsas");
	s.PushBack ("ssssssssssss");
	s.PushBack ("sdasadadafffffffffffffffffffffffffffffffffff");
	s.PushBack ("sdasdas");
	s1.Sort ();
	s1.Display ();
}

void test1()
{
	Stack<int , SeqList<int>> s;
	s.Push (1);
	s.Push (1);
	s.Push (3);
	s.Push (4);
	s.Push (2);
	s.Display ();
}
int main()
{
	test1();
	system("pause");
	return 0;
}


-----------------------------------------------------------------------------------------------------

模板参数实现队列


// 模板参数模拟实现队列

#include<iostream>

using namespace std;

template<typename T>
struct Node
{
	Node(const T& d)
		:_next(NULL)
		,_prev(NULL)
		,_data(d)
	{}

	T _data;
	Node<T>* _next;
	Node<T>* _prev;
};

template<typename T>
class LinkList
{
public:
	LinkList ()
		:_head(NULL)
		,_tail(NULL)
	{}

	~LinkList ()
	{
		Node<T>* cur =_head;

		while(cur)
		{
			Node<T>* tmp = cur;
			cur = cur->_next ;
			delete tmp;
		}

		_head = _tail = NULL;
	}

	void PushBack(const T& data);
	void PushFront(const T& data);
	void PopBack();
	void PopFront();
	void Remove(const T& data);
	void RemoveAll(const T& data);
	void Sort();
	void Display();
	Node<T>* GetHead()
	{
		return _head;
	}
private:

	Node<T>* _head;
	Node<T>* _tail;
};

template<typename T>
void LinkList<T>::PushBack(const T& data)
{
	Node<T>* pNode = new Node<T>(data);
	if(_head==NULL)
	{
		_head = _tail = pNode; 
	}
	else
	{
		_tail->_next = pNode;
		pNode->_prev = _tail;
		_tail = pNode ;
	}
}

template<typename T>
void LinkList <T>::PushFront(const T& data)
{
	Node<T>* pNode = new Node<T>(data);

	if(_head==NULL)
	{
		_head = _tail = pNode;
	}
	else
	{
		pNode->_next = _head;
		_head->_prev = pNode;
		_head = pNode;
	}
}

template<typename T>
void LinkList <T>::PopBack ()
{
	if(_head==NULL)
		return;
	else if(_head->_next == NULL)
	{
		delete _head;
		_head = _tail = NULL;
	}
	else
	{
		Node<T>* tmp = _tail;
	    _tail = _tail->_prev ;
	    _tail->_next = NULL;
	    delete tmp;
	}
}

template<typename T>
void LinkList <T>::PopFront ()
{
	if(_head==NULL)
		return;
	Node<T>* tmp = _head;
	_head->_prev = NULL;
	_head = _head->_next ;
	delete tmp;
}

template<typename T>
void LinkList <T>::Remove (const T& data)
{
	Node<T>* cur = _head;

	while(cur)
	{
		if(cur->_data == data)
		{
			if(cur->_prev == NULL)
			{
				PopFront ();
			}
			else if(cur->_next == NULL)
			{
				PopBack ();
			}
			else
			{
				Node<T>* t = cur;
				cur->_next ->_prev = cur->_prev ;
				cur->_prev ->_next = cur->_next ;
				delete t;
			}
			return;
		}
		cur = cur->_next ;
	}
}

template<typename T>
void LinkList<T>::RemoveAll (const T& data)
{
	Node<T>* cur = _head;

	while(cur)
	{

		if(cur->_data == data)
		{
			if(cur == _head)
			{
				cur = cur->_next ;
				PopFront ();
				
			}
			else if(cur->_next == NULL)
			{
				PopBack ();
				cur = NULL;
				break;
			}
			else
			{

				/*Node<T>* t = cur->_next;
				cur->_next ->_prev = cur->_prev ;
				cur->_prev ->_next = cur->_next ;
				delete cur;
				cur = t;*/
				cur->_data = _tail->_data ;
				PopBack();
			}
		}
		else
			cur = cur->_next ;
	}
}

template<typename T>
void LinkList <T>::Sort ()
{
	//链表的冒泡排序;

   Node<T>* cur = NULL;
   Node<T>* teil = NULL;

	cur = _head ;

	while(cur != teil)
	{
		while(cur->_next != teil)
		{
			if(cur->_data > cur->_next ->_data )
			{
				T tmp = cur->_data ;
				cur->_data = cur->_next ->_data ;
				cur->_next ->_data = tmp;
			}
			cur = cur->_next ;
		}
		teil = cur;
		cur = _head;
	}
	return ;
}

template<typename T>
void LinkList<T>::Display()
{
	Node<T>* tmp = _head;

	while(tmp)
	{
		cout<<tmp->_data<<"  ";
		tmp = tmp->_next;
	}
	cout<<endl;
}

template<typename T,typename Container>
class Queue
{
public:
	bool Empty()
	{
		return _con.GetHead() == NULL;
	}
	Node<T>& Front()
	{
		return *_con.GetHead();  
	}
	void Back(const T& data)
	{
		
	}
	void Push(const T& data)
	{
		_con.PushBack(data);
	}
	void Pop()
	{
		_con.PopFront();
	}
	void Dispaly()
	{
		while(!Empty())
		{
			cout<<Front()._data<<endl;
			Pop(); 
		}
	}
private:
	Container _con;
};

void test1()
{
	Queue<int , LinkList<int> > s;
	s.Push (1);
	s.Push (1);
	s.Push (1);
	s.Push (2);
	s.Dispaly ();
}

void  test()
{
	LinkList<int> l;
	l.PushBack (1);
	l.PushBack (4);
	l.PushBack (2);
	l.PushBack (1);
	l.PushBack (2);
	l.PushBack (6);
	l.PushFront (4);
	l.Sort ();
	//l.Remove (1);
	//l.RemoveAll (3);
	//l.PopBack ();
	/*l.PopBack ();
	l.PushFront (4);
	l.PopFront ();*/
	l.Display ();

}

int main()
{
	test1();
	system("pause");
	return 0;
}


  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值