简述C++泛型化编程思想

1、泛型的基本思想

泛型编程(Generic Programming)是一种语言机制,通过它可以实现一个标准的容器库。像类一样,泛型也是一种抽象数据类型,但是泛型不属于面向对象,它是面向对象的补充和发展。泛型编程在C++上的应用主要体现在两方面:函数模板类模板,接下来我们通过两个例子说明。

1)函数模板

泛型,也就是我们说的任何类型,即不依赖于任何具体的类型。通常我们的操作都是依赖于具体的数据类型的,比如:

int add(int a, int b)
{
     return a + b;
}

这个add函数依赖于int类型。你只能以int类型调用(即使是float,也会被转换为int型)。得到的结果也只能是int。那如果我们还需要一个float类型的add算法,就需要再写一个重载程序:

float add(float a, float b)
{
     return a + b;
}

虽然在C++中可以通过函数重载来解决这个问题,但是反复写相同算法的函数是比较辛苦的,更重要的是函数重载是静态编译,运行时占用过多内存。

而泛型依赖于模板技术,可以支持任意数据类型,比如:

template <class T>
T add( T a, T b)
{
     return a + b;
}

这个函数就可以用int,float等类型进行实例化,然后进行调用,这就不依赖任何具体的数据类型。例如:

int result = add<int>(1,2);
string result = add<string>("hello","world");

2)类模板

比如对栈的描述:

class stack{

push(参数类型);  //入栈

pop(参数类型);  //出栈

如果把上面的伪代码看作算法描述,没问题,因为算法与参数类型无关。但是如果把它写成可编译的源代码,就必须指明类型,否则是无法通过编译的。使用重载来解决这个问题,即对N种不同的参数类型写N个push和pop算法,这样是很麻烦的。

若对上面的描述进行改造如下:

首先指定一种通用类型T,不具体指明是哪一种数据类型:

class stack<参数模板T>

{

push(T);  //入栈算法

pop(T);  //出栈算法

}

这里的参数模板T相当于一个占位符,当我们实例化stack时,T会被具体的数据类型替换掉。

若定义对象S为stack类型,在实例化S时若我们将T指定int型,则:

class S
{
     push(int);  //入栈
     pop(int);  //出栈
}

这时,我们可以称class stack<参数模板T>是 类的类,通过它可以生成具体参数类型不同的类。

综上,可以看出泛型在C++中的应用主要是模板函数模板类

2、定义模板函数

函数模板是一个独立于类型的函数,可以产生函数的特定类型版本。

模板定义以关键字template开始,后接尖括号括住的模板形参表。

模板形参可以是表示类型的类型形参(type parameter),也可以是表示常量表达式的非类型形参(nontype parameter)。如下面的程序中的T是类型形参。

/*
 implement strcmp-like generic compare function
*/
#include <iostream>
#include <string>
using namespace std;


template <typename T> //类型形参,若多个类型形参,则<typename T1, typename T2>
int compare(const T &v1, const T &v2)
{
	if(v1 < v2)	return -1;
	if(v2 < v1)	return 1;
 	return 0;
}


int main()
{
	cout << compare(1,2) << endl;
	
	string s1 = "hello", s2 = "world";
	cout << compare(s1, s2) << endl;
	return 0;
}

使用函数模板时,编译器会将模板实参绑定到模板形参。编译器将确定用什么类型代替每个类型形参,用什么值代替每个非类型形参,然后产生并编译(称为实例化)该版本的函数。

上面的例子中,编译器用int代替T创建第一个版本,用string代替T创建第二个版本。

3、定义模板类

在定义的类模板中,使用模板形参作为类型或值的占位符,在使用类时再提供具体的类型或值。例如:

template <typename T>
class Queue
{
public:
	Queue();
	T &front();
	const T & front() const;
	void push(const T&);
	void pop();
	bool empty()const;
private:
	//...
};

与调用函数模板不同,实用类模板时,必须为模板形参指明指定数据类型,例如:

Queue<int> qi; // Queue that holds ints
Queue<string> qs; // Queue that holds strings







  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值