驾校官方网站 模板,wordpress投稿收费,企业网站建设的研究开发方法及技术路线,无锡专业网站营销目录 概述
函数模板
1.函数模板的定义
2.函数模板的使用
3.非类型的模板参数
类模板
1.函数模板的定义
2.类模板的成员函数
3.模板类名字的使用
4.非类型的模板参数 概述
泛型编程是一种编程思想#xff0c;其追求摆脱数据类型的束缚#xff0c;通过将数据类型作为…目录 概述
函数模板
1.函数模板的定义
2.函数模板的使用
3.非类型的模板参数
类模板
1.函数模板的定义
2.类模板的成员函数
3.模板类名字的使用
4.非类型的模板参数 概述
泛型编程是一种编程思想其追求摆脱数据类型的束缚通过将数据类型作为参数的处理提高代码的通用性。模板是泛型编程的基础它支持将数据类型作为参数从而使得我们在处理具有相似性的对不同数据类型的处理时大大减少类代码量。模板在定义时并不会占有内存而是在我们使用模板时针对我们的参数具体产生一个处理此类参数的函数/类并在此时分配内存这个过程就叫做模板的实例化。
模板大致可以分为函数模板和类模板。两者有很多相似之处但也略有不同。
函数模板
1.函数模板的定义
下面提供简单的函数模板定义代码
templateclass T//此处class并不是定义类而是标注T代表一个类型名。
//class也可以用typename替代作用相同
void CoutInformation(T a)//此处为函数CoutInformation的形参列表。
{
coutaendl;
}CoutInformationint(5);//显式
char a(666);
CoutInformation(a);//隐式
定义模板使用template关键字与相连的内的是模板参数列表可以在此处列出需要的类型多个类型要使用多个class或者typename并用逗号隔开但不建议class和typename混用。class和typename 可以标志T为类型参数这里T也是自主起的来代替类型的名称可以自主选择。编译器允许定义模板函数同名的函数如果条件相同编译器会优先调用非模板函数且不会在生成此模板函数的实例化版本。
一般我们将把函数模板的定义放在.h文件中在用include将其包含到.cpp文件中。不需要考虑函数模板的重定义问题。
模板函数可以写成内联函数inline声明写于与函数返回类型之间。
2.函数模板的使用
当我们调用模板函数时我们可以使用尖括号明确表示我们的参数类型也可以省略尖括号让编译器自主帮我们推断参数类型。函数参数都有了明确的类型编译器就会实例化出针对此类型的实例化版本当我们再次调用相同类型的参数时编译器就会调用模板函数的实例化版本不会再二次实例化。但我们省略模板参数列表时我们要确保编译器可以通过我们传递的函数实参推断出模板参数列表中的内容。当我们使用明确模板参数的时候要确保与函数实参的类型相匹配。
我们可以这样认为模板函数的定义并不会让编译器生成代码只有在我们调用函数模板时编译器为我们实例化特定版本的函数之后编译器才生成代码。也就是说函数模板就像一张图纸一样一旦我们有了图纸中的参数我们就可以通过这些参数具体的将图纸中的内容建设出来。
3.非类型的模板参数
templatetypename T,int a//a为非类型模板参数
int CoutInformation(T b)
{
coutbendl;
return a;
}int c520;
int dCoutInformationint,100(a);
模板参数不仅仅是类型参数也可以是非类型参数也就是一段数据。对于非类型参数我们需要用具体的数据类型来修饰。这些非类型模板参数同样可以被编译器推断如果编译器无法推断出这些非类型模板参数的值就需要我们使用具体的给它提供值。同时需要注意的是模板实例化发生在编译的过程。因此我们使用提供的模板参数都应该为常量表达式否则编译器将会报错。
下面提供特殊示例
#includeiostream
using namespace std;
templateunsigned L1,unsigned L2
void Coutchar(const char a[L1],const b[L2])
{
coutaandbendl;
}
int main()
{
Coutchar(yes,no);//此时非类型模板参数L1,L2就是编译器推断的//但是如果我们使用54提供非类型模板参数编译反而会报错//因为系统推断yes长度为4no长度为3传递参数与系统推断不符
}
类模板
1.函数模板的定义
templatetypename T
class Goodclassname
{
public :void CoutInformation(){coutaendl;}
private :T a;
};
和函数模板相似我们也可以通过类模板的实例化功能来避免代码的重复性。但需要注意的是类模板并不能像函数模板那样推断模板参数的内容也就是说我们必须使用来明确类模板参数的内容。同时类模板也可以在模板参数列表中设定默认参数值。
2.类模板的成员函数
如果我们将类模板的成员函数的函数体写在类模板定义的内部和普通类成员函数一样其也会被隐式声明为内联函数。如果我们将类模板的成员函数的函数体写在类模板定义的外部那我们就需要标明类模板的模板参数也就是在函数前使用template同时在尖括号内将所有模板参数名列出多个模板参数之间用逗号分隔。这是因为类模板一旦被实例化之后就会产生自己版本的成员函数也就是说类模板的成员函数拥有与类模板相同的模板参数。
一个类模板可以有多个成员函数。当类模板被实例化时并不是说全部的成员函数都将被实例化。而是实例化那些被使用过的成员函数。也就是说一个类模板的成员函数只有在使用的时候才被实例化。
templateclass T
class Goodclassname
{
public:void CoutInformation();
private:T a;
};templateclass T
void GoodclassnameT::CoutInformation()
{coutaendl;
}
3.模板类名字的使用
在类模板定义内部我们直接使用类模板的名字并不需要带上类模板参数因为系统默认模板类内的成员的模板参数与模板类保持一致。但是我们在类模板定义外面使用类模板名称的时候应在类模板名字后使用列出模板参数因为这样才能表示的是一个已经被实例化的类模板。
当非模板类子类继承模板类父类时应该明确父类中模板参数的类型这样才可以确定子类的内存。否则子类也应定义为模板类再用子类的模板参数给父类模板参数中确定模板类型这样可以提高父类的灵活性。
templateclass T
class Fathername//父类
{
public:
T a;
};
templateclass R,class P
class Sonname :public FathermameR//子类
{
public:
P b;
};
4.非类型的模板参数
类模板参数同样不局限与类型也可以拥有非类型的模板参数。但是需要注意的是浮点型类型型不能当做非类型模板参数传递。
templateclass Tint a1;
class Goodclassname
{
public:int CoutInformation();
private:T a;
};templateclass T,int a
int GoodclassnameT,a::CoutInformation()
{coutaendl;return a;
}