1.类模板
-
类模板:将类定义中的数据类型参数化,用参数来传递
eg:vector,表示vector内部所存放的数据类型是int,以此类推,vector -
类模板实际上是函数模板的推广,可以用相同的类模板来组建任意类型的对象集合
eg:vector,int类型对象的集合vector,vector,字符串类型的集合string -
类模板的定义
直接用代码说话!
template <类型形参表>
class <类名>
{
//类说明体 };
template <类型形参表>
<返回类型> <类名> <类型名表>::<成员函数1>(形参表)
{
//成员函数定义体 }
template <类型形参表>
<返回类型> <类名> <类型名表>::<成员函数2>(形参表)
{
//成员函数定义体 }
…
template <类型形参表>
<返回类型> <类名> <类型名表>::<成员函数n>(形参表)
{
//成员函数定义体 }
- 使用类模板
(1)类模板的实例化:用具体的数据类型替换模板的参数以得到具体的类(模板类)
(2)模板类也可以实例化为对象
(3)用下列方式创建类模板的实例:
类名 <类型实参表> 对象名称;
类模板不是类,首先要实例化出模板类,好像是函数模板,它不是函数,要先实例化出模板函数出来,才能出来。
与函数模板不同,类模板只能显式实例化为模板类,函数模板可以根据所传送的数据类型不同来自动推导,而类模板只能显式实例化
- eg:用连续的内存空间实现栈,并以模板的实现提供,这样栈可以存放任意类型
P69\Stack.h
#ifndef _STACK_H
#define _STACK_H
#include <exception>
//Stack是一个模板,并不是一个类
//typename T:将类型作为参数来传递,typename T是类型参数
template <typename T>
class Stack
{
public:
//分配一个T类型的连续内存空间
explicit Stack(int maxsize);
~Stack();
void Push(const T& elem);
void Pop();
T& Top();//返回栈顶元素,不带const说明可以改变栈内部的数据
const T& Top() const;//返回栈顶元素,带const说明不能改变栈内部的数据
bool Empty() const;//说明栈是否是空的
private:
T* elems_;
int maxSize_;
int top_;//当前的栈顶位置
};
//类的实现可以放在类说明的外部
//每个成员函数看成是一个函数模板
//Stack<T>表示模板,Stack是成员函数
template <typename T>
Stack<T>::Stack(int maxsize) : maxSize_(maxsize), top_(-1)
{
elems_ = new T[maxsize];
}
template <typename T>
Stack<T>::~Stack()
{
delete[] elems_;
}
template <typename T>
void Stack<T>::Push(const T& elem)
{
//top+1才是是元素的个数
if (top +1 >= maxSize_)
throw out_of_range(“Stack<>::Push() stack full”);//out_of_range是标准库的异常
elems_[top_++] = elem;
}
template <typename T>
void Stack<T>::Pop(const T& elem)
{
//top+1才是是元素的个数
if (top +1 == 0)
throw out_of_range(“Stack<>::Pop() stack empty”);//out_of_range是标准库的异常
--top_;
}
template <typename T>
T& Stack<T>::Top()
{
//top+1才是是元素的个数
if (top +1 == 0)
throw out_of_range(“Stack<>::Top() stack empty”);//out_of_range是标准库的异常
return elems_[top_];
}
template <typename T>
const T& Stack<T>::Top() const
{
//top+1才是是元素的个数
if (top +1 == 0)
throw out_of_range(“Stack<>::Top() const stack empty”);//out_of_range是标准库的异常
return elems_[top_];
}
template <typename T>
bool Stack<T>::Empty() const
{
return top_ + 1 == 0;
}
#endif //_STACK_H
P69\01.cpp
#include "Stack.h"
int main(void)
{
//显示的实例化一个int类型的模板类,而不是自动推导的
//Stack是一个模板,Stack<int>是一个模板类
Stack<int> s(10);//当我们使用时,Stack<int>进行实例化,是在编译器完成的,会将头文件里面的template
//那些东西用int类型来替换,模板实际上是宏和重载的结合,只是说重载的版本是编译器维护的,而不是程序员
s.Push(1);
s.Push(2);
s.Push(3);
while (!s.Empty())
{
cout<<s.Top()<<endl;
s.Pop();
}
return 0;
}
- 测试:
2.非类型模板参数
-
对于函数模板与类模板,模板参数并不局限于类型,普通值也可以作为模板参数
将值作为模板的参数也是可以的 -
eg:
P69\Stack2.h
#ifndef _STACK2_H
#define _STACK2_H
#include <exception>
//Stack2是一个模板,并不是一个类
//typename T:将类型作为参数来传递,typename T是类型参数,int MAX_SIZE是非类型参数
template <typename T, int MAX_SIZE>
class Stack2
{
public:
//分配一个T类型的连续内存空间
Stack2();
~Stack2();
void Push(const T& elem);
void Pop();
T& Top();//返回栈顶元素,不带const说明可以改变栈内部的数据
const T& Top() const;//返回栈顶元素,带const说明不能改变栈内部的数据
bool Empty() const;//说明栈是否是空的
private:
T* elems_;
// int maxSize_;
int top_;//当前的栈顶位置
};
//类的实现可以放在类说明的外部
//每个成员函数看成是一个函数模板
//Stack2<T, int MAX_SIZE>表示模板,Stack2是成员函数
template <typename T, int MAX_SIZE>
Stack2<T, int MAX_SIZE>::Stack2() : top_(-1)
{
elems_ = new T[MAX_SIZE];
}
template <typename T, int MAX_SIZE>
Stack2<T, int MAX_SIZE>::~Stack2()
{
delete[] elems_;
}
template <typename T, int MAX_SIZE>
void Stack2<T, int MAX_SIZE>::Push(const T& elem)
{
//top+1才是是元素的个数
if (top +1 >= MAX_SIZE)
throw out_of_range(“Stack2<>::Push() stack full”);//out_of_range是标准库的异常
elems_[top_++] = elem;
}
template <typename T, int MAX_SIZE>
void Stack2<T, int MAX_SIZE>::Pop(const T& elem)
{
//top+1才是是元素的个数
if (top +1 == 0)
throw out_of_range(“Stack2<>::Pop() stack empty”);//out_of_range是标准库的异常
--top_;
}
template <typename T, int MAX_SIZE>
T& Stack2<T, int MAX_SIZE>::Top()
{
//top+1才是是元素的个数
if (top +1 == 0)
throw out_of_range(“Stack2<>::Top() stack empty”);//out_of_range是标准库的异常
return elems_[top_];
}
template <typename T, int MAX_SIZE>
const T& Stack2<T, int MAX_SIZE>::Top() const
{
//top+1才是是元素的个数
if (top +1 == 0)
throw out_of_range(“Stack2<>::Top() const stack empty”);//out_of_range是标准库的异常
return elems_[top_];
}
template <typename T, int MAX_SIZE>
bool Stack2<T, int MAX_SIZE>::Empty() const
{
return top_ + 1 == 0;
}
#endif //_STACK2_H
P69\02.cpp
#include "Stack2.h"
int main(void)
{
//显示的实例化一个int类型的模板类,而不是自动推导的
//Stack是一个模板,Stack<int>是一个模板类
Stack2<int, 10> s;//当我们使用时,Stack<int>进行实例化,是在编译器完成的,会将头文件里面的template
//那些东西用int类型来替换,模板实际上是宏和重载的结合,只是说重载的版本是编译器维护的,而不是程序员
s.Push(1);
s.Push(2);
s.Push(3);
while (!s.Empty())
{
cout<<s.Top()<<endl;
s.Pop();
}
return 0;
}
-
测试:
-
进一步:C++非类型模板参数
今天的文章类模板的模板类型参数_ppt模板 简约版分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/83790.html