手把手教你C++——模版
文章目录模版初阶1 泛型编程2.模版2.1 函数模版概念2.2 函数模版格式2.3 函数模版的原理2.4 函数模版的实例化2.5 模版参数的匹配原则3. 类模版3.1 类模版的定义格式3.2 模版实例化模版初阶1 泛型编程泛型编程编写与类型无关的通用代码是代码复用的一种手段模版是泛型编程的基础我们在C语言中如果要实现一个交换函数那它支持的就是一种类型的交换比如int、double等那我们能不能提高效率来写一个通用的交换函数呢我们之前虽然已经了解过函数重载但是函数重载还是有它的缺点重载的函数仅仅是类型不同代码的复用率是比较低的。而且只要有新类型出现那我们还是得自己增加新的函数代码的可维护性也会降低可能会出现一个出错所有的重载都会出错的问题那可不可以给编译器一种像模版一样的东西让编译器根据不同类型按照模版来生成代码呢C中就给出了模版2.模版2.1 函数模版概念函数模版代表了一个函数家族该函数模版与类型无关在使用时被参数化根据实参类型产出具体的函数类型版本。2.2 函数模版格式templatetypename 1,typename 2,typename N返回值类型 函数名(参数列表){ }注意typename是用来定义模版参数的关键字也可以使用class(切记不能用struct来代替class)2.3 函数模版的原理函数模版是一个蓝图它本身并不是函数是编译器使用并且生成特点类型函数的模具。所以其实模版就是将本来我们要做的重复的事情交给了编译器就像上面我们用模版之后交换int类型的变量和交换double类型的变量时他们实质上调用的并不是同一个函数只是编译器按照模版生成了特定类型的函数我们可以转换到反汇编来看可以看见函数两个函数的地址是不一样的所以也就可以证明调用的根本就不是同一个函数在编译器编译阶段编译器需要通过具体传入的实参来推演生成特定类型的函数以供调用。比如当用double类型使用模版时编译器通过对实参类型的推演将T确定为double类型然后产生一份专门处理double类型的代码对于字符类型也是如此2.4 函数模版的实例化用不同类型的参数使用函数模版时就叫做函数模版的实例化。实例化分为显示实例化和隐式实例化隐式实例化让编译器通过实参来推演模版参数的实际类型像这里我们给Add这个函数不同类型的实参的时候就会出现报错是因为编译器无法通过实参来推演模版参数的实际类型它不知道最后一个生成一个int类型还是double类型那我们就可以使用隐式类型转换把两个变量的其中一个强制转换为与另一个变量相同的类型显示类型转换在函数名后的中指定模版参数的实际类型如果类型不匹配编译器会尝试隐式类型转换如果无法转换成功则会报错2.5 模版参数的匹配原则一个非模版函数可以和同名的函数模版同时存在而且该函数模版还可以被实例化为这个非模版函数像这里这个Add函数与非模版函数完全匹配不需要函数模版实例化模板函数不允许自动类型转换但普通函数可以进行自动类型转换给两个类型不同的变量还是会调用第一个函数因为对于模版来说无法通过实参来推演具体类型的函数所以最终就会调用那个非模版函数将double类型的变量隐式类型转换为int3. 类模版3.1 类模版的定义格式比如我们之前定义不同类型的栈就需要逐个去写有了模版之后如上只需要显示实例化就可以用同一个模版来实现不同类型的栈。不再用程序员逐个生成模版其实就是将重复的工作减去大大提高了效率3.2 模版实例化类模版实例化和函数模版实例化不同类模版实例化需要在类后面跟,然后将实例化的类型放在中就好类模版的名字不是真正的类实例化的结果才是真正的类