C++类模板
在上篇文章(C++函数模板)中,主要介绍了C++中函数模板,与函数相似,类也可以被一种或多种类型参数化。容器类就是一个具有这种特性的典型的例子,
本文地址:http://www.cnblogs.com/archimedes/p/cpp-class-template.html,转载请注明源地址。
以下通过设计一个类模板Stack的实现来说明:
类模板Stack的实现
#include<iostream>
#include<vector>
#include<stdexcept>
#include<string>
#include<cstdlib>
using namespace std; template<typename T>
class Stack
{
private:
vector<T> elems; //存储元素的容器
public:
void push(T const&); //压入元素
void pop(); //弹出元素
T top() const; //返回栈顶元素
bool empty() const { //返回栈是否为空
return elems.empty();
}
}; template<typename T>
void Stack<T>::push(T const& elem)
{
elems.push_back(elem);
} template<typename T>
void Stack<T>::pop()
{
if(elems.empty()) {
throw out_of_range("Stack<>::pop(): empty stack");
}
elems.pop_back();
} template<typename T>
T Stack<T>::top() const
{
if(elems.empty()) {
throw out_of_range("Stack<>::top(): empty stack");
}
return elems.back();
}
可以发现,类模板Stack<>是通过C++标准库vector<>来实现的,我们可以不需要亲自设计内存管理、拷贝构造函数和赋值运算
类模板Stack的使用
为了使用类模板对象,必须显式地指定模板实参,下面的例子展示了如何使用类模板Stack<>:
int main()
{
try{
Stack<int> intStack;
Stack<string> stringStack; intStack.push();
cout<<intStack.top()<<endl; stringStack.push("hello");
cout<<stringStack.top()<<endl;
stringStack.pop();
stringStack.pop();
}
catch(exception const& ex) {
cerr<<"Exception: "<<ex.what()<<endl;
//return EXIT_FAILURE;
}
cin.get();
return ;
}
通过声明类型Stack<int>,在类模板内部就可以用int实例化T。因此,intStack是一个创建自Stack<int>的对象,它的元素存储于vector,且类型为int,类似,如果声明和使用Stack<string>将会创建相应的对象。
对于类模板,成员函数只有在被使用的时候才被实例化。
显然,这样可以节省时间和空间,另一个好处是:对于那些“未能提供所有成员函数中所有操作的”类型,你可以使用该类型来实例化类模板,只要对那些“未能提供某些操作的”成员函数,模板内部不使用就可以。
你可以像使用其他任何类型一样地使用实例化后的类模板类型(例如Stack<int>),只要它支持所调用的操作就可以:
void foo(Stack<int> const& s)
{
Stack<int> istack[];
...
}
借助于typedef,可以方便的使用类模板:
typedef Stack<int> IntStack;
void foo(IntStack const& s)
{
IntStack<int> istack[];
...
}
类模板的特化
可以使用模板实参来特化类模板,和函数模板的重载类似,通过特化类模板,你可以优化基于某种特定类型的实现,或者克服某种特定类型在实例化类模板时所出现的不足。
为了特化一个类,你必须在起始处声明一个template<>,接下来声明用来特化类模板的类型:
template<>
class Stack<string> {
private:
deque<string> elems;
public:
void push(string const&);
void pop();
string top() const;
bool empty() const {
return elems.empty();
}
}; void Stack<string>::push(string const& elem)
{
elems.push_back(elem);
} void Stack<string>::pop()
{
if(elems.empty()) {
out_of_range("Stack<string>::pop(): empty stack");
}
elems.pop_back();
} string Stack<string>::top()
{
if(elems.empty()) {
out_of_range("Stack<string>::top(): empty stack");
}
return elems.back();
}
C++类模板的更多相关文章
- C++STL - 类模板
类的成员变量,成员函数,成员类型,以及基类中如果包含参数化的类型,那么该类就是一个类模板 1.定义 template<typename 类型形参1, typename 类型形参2,...&g ...
- C++ 类模板的使用
从事C++挺久了,在前段时看书时,发现高手,都是在写模板无,泛型编程,顿感差距.自己连模板都没有写,于是就小小的研究了下模板的用法. 模板简而言之就是对某此对象的相同方法,或处理方式,进行归纳,总结, ...
- Xcode6中如何使用自定义的类模板
说到IOS类的模板,有些人感觉很陌生,但是只要有开发过IOS程序的人,其实都用过类的模板,只不过是用的系统自带的类的模板. 例如创建一个ClassTemplateVC继承于UIViewControll ...
- VS2013,VS2015设置类模板文件表头
一般VS的类模板文件是放在C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ItemTemplatesCache\CSha ...
- 不可或缺 Windows Native (19) - C++: 对象的动态创建和释放, 对象的赋值和复制, 静态属性和静态函数, 类模板
[源码下载] 不可或缺 Windows Native (19) - C++: 对象的动态创建和释放, 对象的赋值和复制, 静态属性和静态函数, 类模板 作者:webabcd 介绍不可或缺 Window ...
- 类模板的static成员
下列代码可以通过编译吗?如何修改使其通过编译? template <class T> struct sum { static void foo(T op1 , T op2){ c ...
- 4.1 pair类模板
在学习关联容器之前,首先先要了解一下STL中的pair类模板,因为关联容器的一些成员函数返回值都是pair对象,而且map 和multimap中的元素都是pair对象. 1)pair类模板定义 pai ...
- 3.2 STL中的函数对象类模板
*: STL中有一些函数对象类模板,如下所示: 1)例如要求两个double类型的x 和y 的积,可以: multiplies<double>()(x,y); 该表达式的值就是x*y的值. ...
- [Reprint] C++函数模板与类模板实例解析
这篇文章主要介绍了C++函数模板与类模板,需要的朋友可以参考下 本文针对C++函数模板与类模板进行了较为详尽的实例解析,有助于帮助读者加深对C++函数模板与类模板的理解.具体内容如下: 泛型编程( ...
随机推荐
- SNF开发平台WinForm之二-开发-单表表单管理页面-SNF快速开发平台3.3-Spring.Net.Framework
2.1运行效果: 2.2开发实现: 2.2.1 这个开发与第一个开发操作步骤是一致的,不同之处就是在生成完代码之后,留下如下圈红程序,其它删除. 第一个开发地址:开发-单表表格编辑管理页面 http: ...
- xdebug调试一直等待连接
调试php时一般会启动浏览器,地址栏里一般是 index.php?XDEBUG_SESSION_START=xxx xxx表示调试的ide_key. 开了代理没有关,结果调试时一直无法连上,折腾了好久 ...
- JS设计模式1-单例模式
单例模式是一种常用的模式,有一些对象我们往往只需要一个,比如全局缓存,window对象.单例模式在js开发中单例模式的用途非常广泛,比如页面中有一个登录浮窗,无论单击多少次登录窗口,这个窗口只会创建一 ...
- Android View 之进度条+拖动条+星级评论条....
PS:将来的你会感谢现在奋斗的自己.... 学习内容: 1.进度条 2.拖动条 3.星级评论条 1.进度条... 进图条这东西想必大家是很熟悉的...为了使用户不会觉得应用程序死掉了,因此 ...
- (8)分布式下的爬虫Scrapy应该如何做-图片下载(源码放送)
转载主注明出处:http://www.cnblogs.com/codefish/p/4968260.html 在爬虫中,我们遇到比较多需求就是文件下载以及图片下载,在其它的语言或者框架中,我们可能 ...
- ADO.NET学习系列(三)----做一个登录案例
总体思路.根据用户输入的用户名和密码,来判断,和数据库里面存的是不是一样,如果一样就表明登录成功,否则就登录失败. 方案一: 1.select* from 表名 where username=&quo ...
- 【C#】线程之Task
Task开启线程 有两种启动方式: 1.构造创建线程,然后启动 var taskForAction = new Task(() => { //do something }); taskForAc ...
- ref与out的区别
若要使用 ref 参数,方法定义和调用方法均必须显式使用 ref 关键字,如下面的示例所示. class RefExample { static void Method(ref int i) { // ...
- 无法将类型为“System.Windows.Controls.SelectedItemCollection”的对象强制转换为类型“System.Collections.Generic.IList`1
在WPF中DataGrid 选择事件中获取SelectedItems 报错如下 无法将类型为“System.Windows.Controls.SelectedItemCollection”的对象强制转 ...
- easyui数据网格视图(Datagrid View)的简单应用
下面介绍datagrid的数据网格详细视图和数据网格的分组视图 1.先引用的js和css文件 1)包含eauyui必备的四个文件easyui.css,icon.css, jquery-min.js.j ...