CGAL Cookbook --泛型编程(初识模板)

来源:互联网 发布:电脑没网wifi却有网络 编辑:程序博客网 时间:2024/06/04 19:36

阅读前提

在阅读本博客之前,请读者先确认自己几项基础知识是否具备。一、是否拥有C/C++的基础,而不仅仅是知道C/C++中有”if else”,”for”等语句。二、是否有面向对象的基础。面向对象三个特征:封装、继承、多态 。这里不一一解释什么其意义了。要不然文章过于臃肿。

C/C++之函数模板

include<iostream>bool compare(int a, int b){    if(a < b) return true;    else return false;}int main(int argc, char* argv[]){    int a = 1;    int b = 2;    bool res = compare(1,2);    return 0;}

以上代码很简单,就是比较两个整形大小。可是现在问题来了,如果现在我突然有一个想法,我想使用compare函数比较两个字符串呢?我们要怎么做解决这个问题呢?当然熟悉C/C++的你们肯定会想到重载机制。于是我们有了以下的函数代码:

#include<iosream>#include<string>using namespace std;bool compare(int a, int b){    if(a < b) return true;    else return false; }bool compare(string a, string b){     if(a < b) return true;     else return false;}int main(int argc, char* argv[]){     int a = 0, b = 20;     string c = "abe", d = "nice";     bool res_ab = compare(a,b);     bool res_cd = compare(c,d);     return 0;}

这样就完成了所需要的功能了,可是一个闲着没事找麻烦的阿三突然有一个想法,他想比较两个点对象。阿三说他已经把点的类写好了,现在就想有个比较函数。点的类定义如下:

struct Point_3{Point_3(){};Point_3(double x, double y, double z):_x(x), _y(y), _z(z){};bool operator<(const Point_3& another)const{    if(_x < another._x)        return true;    else if(_x > another._x)        return false;    else{        if(_y < another._y)            return true;        else if(_y > another._y)            return false;        else{            if(_z < another._z)                return true;             else                return false;        }    }};     double _x;     double _y;     double _z;}

这时候如果阿三有个需要,就必须要用compare函数来比较两个点的大小。怎么办呢?还是照着上面那样再加一个函数?有没有发现很麻烦?如果有一天阿涛,阿树都希望你能提供一个能够比较他们的 对象的函数,这是又怎么办?还是那样傻瓜式往上填?代码是不是看起来又臭又长?有没有更好,更简便的方法呢?
答案是肯定的有:模板
它的样子如下:

template<class T>bool compare(const T& a, const T& b){    if(a < b) return true;    else return false;}

这样不管阿三还是阿四就可以直接使用这个函数来满足他们的需求了。于是我们可以这样来调用函数来。

int main(int argc, char* argv[]){    int a = 0, b = 10;    bool res = compare<int>(a, b);    //这样是不是觉得很麻烦?还要指定类型,可以不用指定吗?    //当然可以了,不指定类型直接调用实际启动了c++的模板参数    //推导机制,于是可以有如下写法    bool res_a = compare(a,b);    string d = "abv";    string e = "cde";    bool res_de = compare(d, e);}

说白了,模板函数就是一个函数族,唯一不同就是其类型,里面的代码过程是一模一样的。不过需要注意的是,虽然我们写的代码少了,其实我们只是把我们本该写的代码交给了编译器来写了,以前我们要针对不同的类型写相似代码的函数,有了模板以后,这些写重复代码的工作就全部由编译器来写了。所以值得注意的是,我们调用函数的类型有多少种,编译器就会为了生成多少相应类型的函数。这个过程称为模板实例化,和面向对象的类实例化不同是,前者生成相应的代码,是代码段的生成。后者则是在数据段开辟内存。两者是完全不同的概念。所以后续文章说实例化,我都会加上模板实例化,为了和类的实例化区分开。
此外由于历史原因,模板其实还可以这样写:

template<class T1,class T2,...,class Tn>//此处的...并不表示可变参数的写法,而是省略中间的语句template<typename T1, typename T2, ..., typename Tn>

其实这里面关键字class 和 typename 没有什么不同,只不过class容易误导人,所以一般定义模板的时候使用typename这个关键词比较合适,有些细节我就不多说了。说多了,容易让人恐惧。

0 0