从例子看C++模版
来源:互联网 发布:淘宝卖家旺旺手机版下载 编辑:程序博客网 时间:2024/05/20 19:31
作为现代C++中最具表现力,被应用最广泛的一个语法功能,Templates(模版),无疑应该被仔细研究。自从有了STL,模版渐渐成为现代C++开发的主角。前不久因为老师的作业要求,我稍微学习了一下C++的模版,写一篇入门文,请大神轻喷,谢谢。
首先应该看的是函数模版:这是最简单的模版了。而函数模版中最简单的例子,应该就是max函数了。以下是我写的一个example:
#include <iostream> #include <string> using namespace std; //模版的声明语法 //这里声明了一个tmax模版,其中可能发生变化的只是一个类型T,至于T是什么我们并不关心 template <typename T> T tmax (T a, T b) { return a < b ? b : a; } int main() { cout << tmax(3,4) << endl; cout << tmax(4.9,4.8) << endl; string s1("watch"),s2("which"); cout << tmax(s1,s2) << endl; return 0; }
模版的魅力就在于,它不需要对象的具体类型,只需要支持进行某些方法或者运算符。这里的tmax函数,无论抛给它的是int,double还是string,都能正确使用,虽然实际上实现的机理是不一样的。对于开发者而言,只需要知道对象支持什么功能即可,并不需要考虑对象究竟是什么,这很有Duck Typing的味道。需要注意的是,C++对模版的实现机理,实际上是对每种可能的参数情况分别编译,也就是说,这段代码实际上会产生3个tmax,分别对应int,double和string。
这个例子应该很好看懂。接下来我们看类模版:
#include <cstdio>#include <cstring>#include <cstdlib>//声明一个模版,接收参数分别是类型名T和一个整数Ntemplate <typename T,int N>class Matrix{public: T d[N][N]; T sum() { T ret=0; for (int i=0;i<N;++i) { for (int j=0;j<N;++j) { ret+=d[i][j]; } } return ret; } T fill(T x) { for (int i=0;i<N;++i) { for (int j=0;j<N;++j) { d[i][j]=x; } } }};Matrix <double, 3> M;int main(){ M.fill(0.1); M.d[1][2]+=4.5; printf("%lf\n",M.sum()); return 0;}
这个例子中,你会发现模版不一定只接收类型,也可以接收一个变量作为模版参数,而这些参数,可以在声明类的实例的时候使用。至于用法,却简单得让人难以置信。类模版使用的时候需要显式声明模版的参数,这大概是类模版和函数模版最大的区别。因为函数模版的用途只是被调用,而类模版是用来自动构造一些类的,而构造需要必要的参数。实质的实现和函数模版一样,类模版也是按需要编译出一堆东西。我们可以看到,C++模版的本质实际上就是一个复杂而安全的宏语法,它大大扩展了C语言里面简陋的#define,成为一个安全而高效的工具。
现在我们来看第三个例子,也是C++当中最让人叹为观止的例子,这个例子给我们展示了利用模版进行一定程度的函数式编程的方法。
#include <iostream>using namespace std;//这里构造了一个函数对象类Plusatemplate <typename T>class Plusa { private: T a;public: Plusa(T d) { this->a=d; } void operator() (T& x) { x+=a; }}; /* perform (l, r ,a[], f)* 对数组a的l到r施用函数对象f*/template <typename T, typename FUNCT>void perform (int l, int r, T a[], FUNCT f){ for (int i=l;i<r;++i) { f(a[i]); }} int main(){ double t[4]={ -0.2, 1.0, 1.2, 1.6 }; //函数对象plus_half Plusa <double> plus_half(0.5); perform(0,3,t,plus_half); for (int i=0;i<4;++i) { cout << t[i] <<endl; } return 0;}
这个例子中有一个额外的语法:函数对象。如果一个对象,它的()运算符被重载,他就变成了一个函数对象,可以当作函数来调用。如果调用它,它和函数看上去一模一样,但事实上它是个对象,所以它可以被轻易地传递,而且可以像Javascript的闭包那样秘密地储藏一些信息。
有了函数对象,我们可以再写一个模版,接受函数对象并使用函数对象,就像例子中的perform函数。函数指针这样复杂的东西,在C++当中可以轻易地被函数对象取代。基本上STL中所有的有比较功能的模版,全都接收函数对象,足见这个功能被应用的广泛程度。
以上只是一些简单的例子,实际上C++的模版远远不止这么点内容,完全去深入的研究,够写一本书,而且也有这样一本书了:《C++ Templates》。最后,希望大家喜欢C++这门优美的编程语言。
- 从例子看C++模版
- 从例子看C++模版
- 从例子看数据结构
- 从一个例子看WML文档规则
- 从一个例子看内存布局
- 从一个例子看网站发展过程
- 从一个微型例子看“C/C++的内存分配机制”和“数组变量名与指针变量名”
- 从一个微型例子看“C/C++的内存分配机制”和“数组变量名与指针变量名”
- 从一个微型例子看“C/C++的内存分配机制”和“数组变量名与指针变量名”
- 从例子看List的add()方法的工作机制
- 从一个失败的例子看dojo widget的定制
- 从一个例子看Python3.x中序列解包
- 从编译器的角度看C代码
- 从汇编看c语言函数调用
- 从反汇编看C++(一)
- 从 C-41 看 MVVM 和 ReactiveCocoa
- 从汇编看c语言函数调用
- [C/C++]_[简单例子看模板template的特性]
- linux中mysql服务启动和关闭
- HTML网页制作
- JBOSS内存溢出处理
- 视频文件头解析--avi-代码解析
- sharepoint事件接受器
- 从例子看C++模版
- Punycode
- 黑马程序员Objective-C笔记:对象方法,类方法
- 从头开始 - 从 petstore 示例开始学习 webx (1)
- 从如何获取可信赖的ip地址聊起
- tomcat设置虚拟目录
- 代码不是怎么想就怎么写的
- 代码录播:零基础 CSS3 学习 背景
- 02-3. 逆序的三位数(10)