目录
模板
函数模板
显示实例化
类模板
模板特点
模板
模板,就是把一个本来只能对特定类型实现的代码,变成一个模板类型,这个模板类型能转换为任何内置类型,从而让程序员只需要实现一个模板,就能对不同的数据进行操作。模板分为函数模板和类模板
模板使用格式:template<typename T1, typename T2,......,typename Tn>;也可以为:template<class T1, class T2,......,class Tn>。
函数模板
函数模板,就是用模板来实现一个函数,从而让这个函数可以供任何内置类型使用,例如下图:
我们定义T为模板,那么T就可以为任何内置类型,当传入不同类型时,编译器都会自动对应上。当然下面swap(a,b)和swap(c,d)也不是同个swap函数,而是编译器根据我们形参的类型,从而把T转换为形参的类型,然后生成一个swap函数。图中代码会生成一个形参是int类型的函数和一个形参是double类型的函数。
编译器根据我们给的类型,在根据函数模板,生成对应类型的函数;这个过程叫模板的实例化。
如果swap的两个传参不是同个传参,但函数模板里是同个模板T,就会无法编译;这时候只能用显示实例化来强行让两个传参为显示实例化的类型。
显示实例化
进行模板实例化时,还可以显示实例化。即使用模板函数的时候,强制后面的形参为我们所要求的类型。使用方法为:函数模板名<类型>(对象1,对象2....);强制让对象1和对象2为前面<>内输入的类型。
比如下图,直接用add(a,b)是编译不过的,但用了显示实例化就可以强行让a和b都为int类型,再生成一个int类型的add函数,进行调用。
类模板
类模板,就是把模板的类型放入类中,这样在我们类的对象实例化的时候,就可以自主选择需要创建的对象的类型。
注意:类模板创建对象时必须进行显示实例化。
类模板不能声明定义分离到两个文件,在一个文件内进行声明定义分离时,定义部分要包含域和模板类型,而且在定义的上方要在声明一次模板。(因为上面声明的模板,是在class内使用,下面再次声明的模板是在函数内使用)具体使用方式如下图所示:
模板特点
模板不能声明定义分离。
模板只能定义一行使用一行,当模板被使用于函数或者类中后,不能再放入其他函数或者类中。
当模板名字和我们自己定义的函数名冲突时,不会报错;当我们调用函数时,编译器会先找有没有形参对应上的非模板函数,找不到才会实例化模板。但如果使用了显示实例化则会强制调用模板,进行模板实例化。
模板函数不允许自动类型转换,如果类型不同,则编译不了,只能用显示实例化;但普通函数可以进行自动类型转换。
模板可以具有非类型参数(模板可以变为任何内置类型,内置类型有大有小),用于指定大小,可以根据指定的大小创建动态结构,所以模板可以用来创建动态增大或减小的数据结构。
模板运行时不检查数据类型,相当于类型的宏替换,不保证安全。
类模板是一个类家族,模板类是通过类模板实例化的具体类。
C++中类模板的声明格式为template<模板形参表声明><类声明>,并且类模板的成员函数都是模板函数。因为模板可以转为任何类型,所以在类模板中,每个成员函数都有一个this指针代表自己,就会包含这个模板,所以成员函数就是模板函数。比如一个Stack类模板,里面的成员函数一定都是对Stack的数据进行修改操作,而Stack的数据类型是由模板控制的,所以Stack类中的成员函数就都是模板函数。