模板和泛型编程

       所谓泛型编程就是以独立于任何特定类型的方式编写代码。使用泛型程序时,我们需要提供具体程序实例所操作的类型或值。

    在 C++ 中,模板是泛型编程的基础。模板是创建类或函数的蓝图或公式。

     函数模板是一个独立于类型的函数,可作为一种方式,产生函数的特定类型版本。例如,可以编写名为 compare 的函数模板,它告诉编译器如何为我们想要比较的类型产生特定的 compare 版本。下面是 compare 的模板版本:

// implement strcmp-like generic compare function

// returns 0 if the values are equal, 1 if v1 is larger, -1 if v1is smaller

template <typename T>

int compare(const T &v1, const T &v2)

{

if (v1 < v2) return -1;

if (v2 < v1) return 1;

return 0;

}

         模板定义以关键字 template 开始,后接模板形参表,模板形参表是用尖括号括住的一个或多个模板形参的列表,形参之间以逗号分隔。

       模板形参表模板形参表很像函数形参表,函数形参表定义了特定类型的局部变量但并不初始化那些变量,在运行时再提供实参来初始化形参。

     同样,模板形参表示可以在类或函数的定义中使用的类型或值。例如,compare 函数声明一个名为 T 的类型形参。在 compare 内部,可以使用名字 T引用一个类型,T 表示哪个实际类型由编译器根据所用的函数而确定。模板形参可以是表示类型的类型形参,也可以是表示常量表达式的非类型形参。非类型形参跟在类型说明符之后声明。

就像可以定义函数模板一样,也可以定义类模板。

     例

     我们自定义的 Queue 类必须能够支持不同类型的对象,所以将它定义为类模板。Queue 类将支持的操作是标准 queue 类接口的子集:

• push 操作,在队尾增加一项

• pop 操作,从队头删除一项

• front 操作,返回队头元素的引用

• empty 操作,指出队列中是否有元素

这里先定义它的接口:

template <class Type> class Queue {

public:

Queue (); // default constructor

Type &front (); // return element from head of Queue

const Type &front () const;

void push (const Type &); // add element to back of Queue

void pop(); // remove element from head of Queue

bool empty() const; // true if no elements in the Queue

private:

// ...

};

     类模板也是模板,因此必须以关键字 template 开头,后接模板形参表。Queue 模板接受一个名为 Type 的模板类型形参。除了模板形参表外,类模板的定义看起来与任意其他类问相似。类模板可以定义数据成员、函数成员和类型成员,也可以使用访问标号控制对成员的访问,还可以定义构造函数和析构函数等等。在类和类成员的定义中,可以使用模板形参作为类型或值的占位符,在使用类时再提供那些类型或值。

      例如,Queue 模板有一个模板类型形参,可以在任何可以使用类型名字的地方使用该形参。在这个模板定义中,用 Type 指定重载 front 操作的返回类型以及作为 push 操作的形参类型。

      使用类模板与调用函数模板形成对比,使用类模板时,必须为模板形参显式指定实参:

Queue<int> qi; // Queue that holds ints

Queue< vector<double> > qc; // Queue that holds vectors ofdoubles

Queue<string> qs; // Queue that holds strings

     编译器使用实参来实例化这个类的特定类型版本。实质上,编译器用用户提供的实际特定类型代替 Type,重新编写 Queue 类。在这个例子中,编译器将实例化三个 Queue 类:第一个用 int 代替 Type,第二个用 vector<double> 代替 Type,第三个用 string 代替 Type。

     像函数形参一样,程序员为模板形参选择的名字没有本质含义。在我们的例子中,将 compare 的模板类型形参命名为 T,但也可以将它命名为任意名字:

// equivalent template definition

template <class Glorp>

int compare(const Glorp &v1, const Glorp &v2)

{

if (v1 < v2) return -1;

if (v2 < v1) return 1;

return 0;

}

       该代码定义的 compare 模板与前面一样。可以给模板形参赋予的唯一含义是区别形参是类型形参还是非类型形参。如果是类型形参,我们就知道该形参表示未知类型,如果是非类型形参,我们就知道它是一个未知值。

      如果希望使用模板形参所表示的类型或值,可以使用与对应模板形参相同的名字。例compare 函数中所有的 Glorp 引用将在该函数被实例化时确定为同一类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值