C++中的template

今天面一家独角兽公司的时候,被面试官问到这个问题。所幸之前的C++基础还记得一些,基本回答上来了。于是写一个blog来强化一下。


函数模板

函数模板实际上,解决了一个函数多态性过程中所遇到的问题。实际上主要解决的就是形参类型不一的问题。

因为C++是一种静态语言,不像Python那样数据类型等运行起来了再确定,我们用函数或者用变量都必须确定类型。函数需要确定返回值类型,这就使得函数在使用起来不太灵活。

我们来比较C++和python在同一个函数的表现,打个比方,求最大值。

对于Python:

def max(a, b):
    return a if a>=b else b

对于C++: 

int max(int a, int b){
    if(a>=b) return a;
    else return b;
}

看出差别吗,差别就在于C++的函数确定了形参和返回值类型为int,输入两个浮点数这个函数就会报错,比如max(1.0, 2.0)。对于简便的动态语言Python来讲,就不会存在这个问题。那怎么解决C++的这个问题呢?

可以用函数重载。但还不是那么方便,咱们要定义好多种类型的函数才能cover掉python用一个函数解决的,打个比方:

int max(int a, int b){
    if(a>=b) return a;
    else return b;
}

double max(double a, double b){
    if(a>=b) return a;
    else return b;
}


float max(float a, float b){
    if(a>=b) return a;
    else return b;
}

...

仅因为类型不同,我们就定义这么多相同函数体的函数,而且还覆盖不了所有的情况,这确实是非常不方便的。

C++函数模板的出现,就巧妙解决了这个问题:

<template typename T>
T max(T a, T b){
if(a>=b) return a;
    else return b;
}

咱不需要确定a和b的类型,我们先定义了一个类型T,这就是一个模板,T在这里占个坑,以后要什么类型就可以往里面填什么类型。我们同时可以确定多个不同的模板类型,来代表形参之间类型的不同。比如,我要比较一个int类型的数和一个double类型的数,哪个更大。上述模板就不能用了,因为上述模板默认两个形参的类型是一样的。不过,template还是挺灵活的,可以设置多个模板类型,比如:

<template typename T1,typename T2>
T1 max(T1 a, T2 b){
if(a>=b) return a;
    else return b;
}

同时,我们的关键字typename可以完全被class代替,不过通常会建议优先用typename。 


类模板

类模板只是函数模板的一个扩展,即含有用了函数模板的成员方法或用了含有类型模板的类成员。其实,也没有什么函数模板,我们的模板只是类型模板,用在函数里,这个函数就变成了"函数模板",用在类里,这个类就变成了"类模板"。来看一个栗子:

template <typename T>
class Complex{ 
public: //构造函数 
    Complex(T a, T b) { 
        this->a = a; 
        this->b = b;
 } 
private:
     T a;
     T b; 
}; 

如上,Test类里面的类成员,并没有固定它的类型。我们是暂时用T来占坑,这样就给类的实例化留下了很大的空间。我们可以看一下实例化的实现:

int main() {
	//对象的定义,必须声明模板类型,因为要分配内容
	Complex<int> A(10, 20),*pa;
	Complex<double> B(20.0, 30.0), *pb;
	pa = &A;
	pb = &B;
	cout << pa->a << endl;
	cout << pb->a << endl;
	system("pause");
	return 0;
}

就是这么简单,看很多blog都写得那么复杂~~ 

猜你喜欢

转载自blog.csdn.net/leviopku/article/details/83189206