本节知识点:
1.类模板是函数模板的升级:
a. c++中可以将模板的思想应用于类,使得类可以不关注具体所操作的数据类型,而只关注类所需要实现的功能。 b. 函数模板是使一个函数体适合各种类型的数据,类模板是使一个类适合各种类型的数据(包括成员函数和成员变量,当使得成员函数满足各种类型的数据的时候,其实就是在使用函数模板,所以说类模板是函数模板的升级) ,函数模板是类模板中的一部分。 c.类模板常用于一些存储和组织数据元素的类中,如:数组类、链表类、stack类、queue类等2.类模板的语法规则:
a. 类模板的作用就是提供一种特殊的类以相同的行为处理不同的类型 b.类模板的使用跟函数模板的使用一样,在定义类的前面声明template#include
using namespace std;
template
class test { public: int a; T a1; T add(T b, T c) { return b + c; } T min(T b, T c); }; template
T test
::min(T b, T c) { return b - c; } int main() { test
t1; cout << t1.add(4, 6) << endl; cout << t1.min(6, 4) << endl; return 0; }
注意:声明的泛指类型T可用于声明成员变量和成员函数
3.类模板的深入理解:
a. 对于函数模板,编译器进行了两次编译,第一次是直接对函数模板进行编译,看函数模板是否存在语法错误。第二次是在指明类型,让函数模板创建出具体类型的函数,调用具体类型的函数的时候,对具体函数进行编译。最终程序中只存在具体类型的函数,不存在函数模板。 b. 类模板跟函数模板的处理方式是一样的,也是进行两次编译,第一次是对类模板进行编译,判断类模板是否存在语法错误。第二次是在类模板创建出具体类型的对象之后 test4.函数模板与类模板的工程应用:
a. 一般在工程中,函数的实现和函数的调用是在不同的文件中的,类的实现和类的使用也是在不同的文件中的。但是对于函数模板和类模板,模板的实现和使用必须在同一个文件中。因为模板是要在使用的时候,进行二次编译的,如果不在同一个文件中,当使用模板的时候编译器进行二次编译就找不到模板了。会产生链接错误!所以函数模板和类模板不能像普通函数和普通类一样分开实现后,在使用时只包括头文件!必须要把使用和实现放在一起。在工程实践中,一般会把类模板的定义直接放在头文件中,此时使用的头文件不再是 .h文件了,是 .hpp文件。hpp文件,就是告诉程序员,其中存放的是模板的实现,其实在编译的时候,hpp文件中的内容会被包含到#include "test.hpp"指定的cpp文件中去,这里面之所以表面上分开存放在hpp文件和cpp文件中,是为了开发的时候,使得代码工程清晰明了,有层次感!
注意:第一,Operator
#include
#include "test.h"
using namespace std;
int main()
{
test
t1; cout << t1.add(4,6) << endl; return 0; }
test.cpp:
#include "test.h"
template
T test
:: add(T a, T b) { return a + b; }
test.h:
#ifndef TEST_H_
#define TEST_H_
template
class test
{
public:
int a;
T add(T a, T b);
};
#endif
示例代码(正确的):
main.cpp:
#include
#include "test.hpp"
using namespace std;
int main()
{
test
t1; cout << t1.add(4,6) << endl; return 0; }
test.hpp:
#include "test.h"
template
T test
:: add(T a, T b) { return a + b; }
test.h:
#ifndef TEST_H_
#define TEST_H_
template
class test
{
public:
int a;
T add(T a, T b);
};
#endif
5.类模板的特化:
a.类模板是可以被特化的,用template<>声明一个类时,表示这是一个特化类! b. 类模板的特化与函数模板的特化是一样的,这种特化都是不需要进行二次编译的,所以说是编译器事先编译好的,当然这种特化不管是调用与否,都会被编译成为可执行代码的,这一点是与模板的本质区别!d. 注意:编译器会优先选择特化类生成对象!! 示例代码:
#include
using namespace std;
template
//test 类模板 class test { public: T a; T add(T b1, T b2) { return b1 + b2; } }; template <> class test
//test类模板 的 int特化 { public: int add() { cout << "hello int" << endl; return 0; } }; int main() { test
t; cout << t.add() << endl; test
t1; cout << t1.add(2.1, 3.0) << endl; return 0; }
注意:函数模板的特化与类模板的特化有一个最大的区别,就是函数模板与其特化的函数原型必须完全相同(即函数的名称,参数个数必须相同),而类模板与其特化的类仅仅类名相同就行了,类里面的内容可以完全不一样。
6.类模板的局部特化:
a.类模板可以定义多个类型参数,template#include
using namespace std;
template
class test { public: void fun() { cout << "T1 T2 " << endl; } }; template
class test
{ public: void fun() { cout << "T T " << endl; } }; template
class test
{ public: void fun() { cout << "T int" << endl; } }; template
class test
{ public: void fun() { cout << "T1* T2*" << endl; } }; int main() { test
t1; t1.fun(); test
t2; t2.fun(); test
t3; t3.fun(); test
t4; t4.fun(