什么是函数模板和类模板
函数模板是一种抽象函数定义,它代表一类同构函数。通过用户提供的具体参数,C++编译器在编译时刻能够将函数模板实例化,根据同一个模板创建出不同的具体函数,这些函数之间的不同之处主要在于函数内部一些数据类型的不同,而由模板创建的函数的使用方法与一般函数的使用方法相同。函数模板的定义格式如下:
templateFunction_Definition
其中,Function_Definition为函数定义;TYPE_LIST被称为类型参数表,是由—系列代表类型的标识符组成的,其间用逗号分隔,这些标识符的通常风格是由大写字母组成,ARG_LIST称为变量表,其中含有由逗号分隔开的多个变量说明,相当于一般函数定义中的形式参数。前面例题中的 max就是函数模板的一个例子,因此这里不再另外举例。
C++提供的类模板是一种更高层次的抽象的类定义,用于使用相同代码创建不同类模板的定义与函数模板的定义类似,只是把函数摸板中的函数定义部分换作类说明,并对类的成员函数进行定义即可。在类说明中可以使用出现在TYPE_LIST中的各个类型标识以及出现在ARG_LIST中的各变量。
1 template<模版参数表>
2 class<类模板名>
3 {<类模板定义体>},
例如我们需要定义一个表示平面的点(Point)类,这个类有两个成员变量分别表示横坐标和纵坐标,并且这两个坐标的类型可以是int、float、 double等等类型。因此可能写出类似Point_int_int、Point_float_int、Point_float_float等这样的类。通过类模板,我们只需要写一个类。
1 #include
2 using namespace std;
3
4 template
5 class Point_T
6 {
7 public:
8 T1 a; //成员a为T1类型
9 T2 b; //成员b为T2类型
10 Point_T() : a(0), b(0) {} //默认构造函数
11 Point_T(T1 ta, T2 tb) : a(ta), b(tb) {} //带参数的构造函数
12 Point_T& operator=(Point_T &pt); //赋值函数
13 friend Point_T operator +(Point_T &pt1, Point_T &pt2); //重载+
14 };
15
16 template
17 Point_T& Point_T::operator=(Point_T &pt) //赋值函数
18 {
19 this->a = pt.a;
20 this->b = pt.b;
21 return *this;
22 }
23
24 template
25 Point_T operator +(Point_T &pt1, Point_T &pt2) //重载+
26 {
27 Point_T temp;
28 temp.a = pt1.a + pt2.a; //结果对象中的a和b分别为两个参数对象的各自a和b之和
29 temp.b = pt1.b + pt2.b;
30 return temp;
31 }
32
33 template
34 ostream& operator << (ostream& out, Point_T& pt) //重载输出流操作符
35 {
36 out << "(" << pt.a << ", "; //输出(a, b)
37 out << pt.b << ")";
38 return out;
39 }
40
41 int main()
42 {
43 Point_T intPt1(1, 2); //T1和T2都是int
44 Point_T intPt2(3, 4); //T1和T2都是int
45 Point_T floatPt1(1.1f, 2.2f); //T1和T2都是float
46 Point_T floatPt2(3.3f, 4.4f); //T1和T2都是float
47
48 Point_T intTotalPt;
49 Point_T floatTotalPt;
50
51 intTotalPt = intPt1 + intPt2;//类型为Point_T的对象相加
52 floatTotalPt = floatPt1 + floatPt2; //类型为Point_T的对象相加
53
54 cout << intTotalPt << endl; //输出Point_T的对象
55 cout << floatTotalPt << endl; //输出Point_T的对象
56
57 return 0;
58 }
Point_T类就是一个类模板,它的成员a和b分别为T1和T2类型,这里我们还实现了它的构造函数、赋值函数、“+”运算符的重载以及输出流操作符“<<”的重载。
使用Point_T类非常方便,我们可以进行各种类型的组合。
代码43、44行,定义了两个Point_T类的对象intPt1和intPt2,表明这两个对象的成员a和b都是int类型。
代码45、46行,定义了两个Point_T类的对象floatPt1和floatPt2,表明这两个对象的成员a和b都是float类型。
代码51行,对intPt1和intPt2进行对象加法,结果保存到intTotalPt中,此过程先调用“+”函数,再调用了“=”函数。
代码52行,与51行类似,只是相加的对象和结果对象都是Point_T类的对象。
代码54、55行,输出对象intTotalPt和floatTotalPt的内容。
可以看出,通过使用类模板Point_T我们可以创建不同的类,大大提高了代码的可维护性以及可重用性。
有一些概念需要区别:函数模板与模板函数,类模板和模板类是不同的意思
函数模板的重点是模板,它表示的是一个模板,用来生产函数。例如前面例题的max是一个函数模板。而模板函数的重点是函数,它表示的是由一个模板生成而来的函数。例如max,max等都是模板函数。
类模板和模板类的区别与上面的类似,类模板用于生产类,例如Point_T就是一个类模板。而模板类是由一个模板生成而来的类,例如Point_T和Point_T都是模板类。
函数模板和类模板有什么区别?
在面试例题1的程序代码中,我们在使用函数模板max时不一定要必须指明T的类型,函数模板max的实例化是由编译程序在处理函数调用时自动完成的,当调用max(1, 2)时自动生成实例max,而调用max(1.1f, 2.2f)时自动生成实例max。当然也可以显示指定T的类型。
对于本例题的类模板Point_T来说,其实例化必须被显示地指定,比如Point_T、Point_T。
答案:
函数模板是一种抽象函数定义,它代表一类同构函数。类模板是一种更高层次的抽象的类定义。
函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地指定。
类模板不能嵌套(局部类模板)。
类模板中的静态成员仅属于实例化后的类(模板类),不同实例之间不存在共享。
函数模板是一种抽象函数定义,它代表一类同构函数。通过用户提供的具体参数,C++编译器在编译时刻能够将函数模板实例化,根据同一个模板创建出不同的具体函数,这些函数之间的不同之处主要在于函数内部一些数据类型的不同,而由模板创建的函数的使用方法与一般函数的使用方法相同。函数模板的定义格式如下:
templateFunction_Definition
其中,Function_Definition为函数定义;TYPE_LIST被称为类型参数表,是由—系列代表类型的标识符组成的,其间用逗号分隔,这些标识符的通常风格是由大写字母组成,ARG_LIST称为变量表,其中含有由逗号分隔开的多个变量说明,相当于一般函数定义中的形式参数。前面例题中的 max就是函数模板的一个例子,因此这里不再另外举例。
C++提供的类模板是一种更高层次的抽象的类定义,用于使用相同代码创建不同类模板的定义与函数模板的定义类似,只是把函数摸板中的函数定义部分换作类说明,并对类的成员函数进行定义即可。在类说明中可以使用出现在TYPE_LIST中的各个类型标识以及出现在ARG_LIST中的各变量。
1 template<模版参数表>
2 class<类模板名>
3 {<类模板定义体>},
例如我们需要定义一个表示平面的点(Point)类,这个类有两个成员变量分别表示横坐标和纵坐标,并且这两个坐标的类型可以是int、float、 double等等类型。因此可能写出类似Point_int_int、Point_float_int、Point_float_float等这样的类。通过类模板,我们只需要写一个类。
1 #include
2 using namespace std;
3
4 template
5 class Point_T
6 {
7 public:
8 T1 a; //成员a为T1类型
9 T2 b; //成员b为T2类型
10 Point_T() : a(0), b(0) {} //默认构造函数
11 Point_T(T1 ta, T2 tb) : a(ta), b(tb) {} //带参数的构造函数
12 Point_T& operator=(Point_T &pt); //赋值函数
13 friend Point_T operator +(Point_T &pt1, Point_T &pt2); //重载+
14 };
15
16 template
17 Point_T& Point_T::operator=(Point_T &pt) //赋值函数
18 {
19 this->a = pt.a;
20 this->b = pt.b;
21 return *this;
22 }
23
24 template
25 Point_T operator +(Point_T &pt1, Point_T &pt2) //重载+
26 {
27 Point_T temp;
28 temp.a = pt1.a + pt2.a; //结果对象中的a和b分别为两个参数对象的各自a和b之和
29 temp.b = pt1.b + pt2.b;
30 return temp;
31 }
32
33 template
34 ostream& operator << (ostream& out, Point_T& pt) //重载输出流操作符
35 {
36 out << "(" << pt.a << ", "; //输出(a, b)
37 out << pt.b << ")";
38 return out;
39 }
40
41 int main()
42 {
43 Point_T intPt1(1, 2); //T1和T2都是int
44 Point_T intPt2(3, 4); //T1和T2都是int
45 Point_T floatPt1(1.1f, 2.2f); //T1和T2都是float
46 Point_T floatPt2(3.3f, 4.4f); //T1和T2都是float
47
48 Point_T intTotalPt;
49 Point_T floatTotalPt;
50
51 intTotalPt = intPt1 + intPt2;//类型为Point_T的对象相加
52 floatTotalPt = floatPt1 + floatPt2; //类型为Point_T的对象相加
53
54 cout << intTotalPt << endl; //输出Point_T的对象
55 cout << floatTotalPt << endl; //输出Point_T的对象
56
57 return 0;
58 }
Point_T类就是一个类模板,它的成员a和b分别为T1和T2类型,这里我们还实现了它的构造函数、赋值函数、“+”运算符的重载以及输出流操作符“<<”的重载。
使用Point_T类非常方便,我们可以进行各种类型的组合。
代码43、44行,定义了两个Point_T类的对象intPt1和intPt2,表明这两个对象的成员a和b都是int类型。
代码45、46行,定义了两个Point_T类的对象floatPt1和floatPt2,表明这两个对象的成员a和b都是float类型。
代码51行,对intPt1和intPt2进行对象加法,结果保存到intTotalPt中,此过程先调用“+”函数,再调用了“=”函数。
代码52行,与51行类似,只是相加的对象和结果对象都是Point_T类的对象。
代码54、55行,输出对象intTotalPt和floatTotalPt的内容。
可以看出,通过使用类模板Point_T我们可以创建不同的类,大大提高了代码的可维护性以及可重用性。
有一些概念需要区别:函数模板与模板函数,类模板和模板类是不同的意思
函数模板的重点是模板,它表示的是一个模板,用来生产函数。例如前面例题的max是一个函数模板。而模板函数的重点是函数,它表示的是由一个模板生成而来的函数。例如max,max等都是模板函数。
类模板和模板类的区别与上面的类似,类模板用于生产类,例如Point_T就是一个类模板。而模板类是由一个模板生成而来的类,例如Point_T和Point_T都是模板类。
函数模板和类模板有什么区别?
在面试例题1的程序代码中,我们在使用函数模板max时不一定要必须指明T的类型,函数模板max的实例化是由编译程序在处理函数调用时自动完成的,当调用max(1, 2)时自动生成实例max,而调用max(1.1f, 2.2f)时自动生成实例max。当然也可以显示指定T的类型。
对于本例题的类模板Point_T来说,其实例化必须被显示地指定,比如Point_T、Point_T。
答案:
函数模板是一种抽象函数定义,它代表一类同构函数。类模板是一种更高层次的抽象的类定义。
函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地指定。
类模板不能嵌套(局部类模板)。
类模板中的静态成员仅属于实例化后的类(模板类),不同实例之间不存在共享。