c++提供了函数模板(function template.)所谓函数模板,实际上是建立一个通用函 数,其函数类型和形参类型不具体制定,用一个虚拟的类型来代表。这个通用函数 就成为函数模板。凡是函数体相同的函数都可以用这个模板代替,不必定义多个函 数,只需在模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板 中的虚拟类型,从而实现不同函数的功能。 c++提供两种模板机制:函数模板和类 模板 类属 - 类型参数化,又称参数模板 总结: 模板把函数或类要处理的数据类型 参数化,表现为参数的多态性,成为类属。 模板用于表达逻辑结构相同,但具体 数据元素类型不同的数据对象的通用行为。
如何实现一个通用的交换函数呢?
void Swap(int& left, int& right)
{
int temp = left;
left = right;
right = temp;
}
void Swap(double& left, double& right)
{
double temp = left;
left = right;
right = temp;
}
void Swap(char& left, char& right)
{
char temp = left;
left = right;
right = temp;
}
使用函数重载虽然可以实现,但是有一下几个不好的地方: 1. 重载的函数仅仅只是类型不同,代码的复用率比较低,只要有新类型出现时,就需要增加对应的函数 2. 代码的可维护性比较低,一个出错可能所有的重载均出错 那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?
函数模板格式
template
返回值类型 函数名(参数列表){}
templatevoid Swap( T& left, T& right) { T temp = left; left = right; right = temp; }
二、函数模板和普通函数区别
函数模板不允许自动类型转化 普通函数能够自动进行类型转
//函数模板 templateT MyPlus(T a, T b){ T ret = a + b; return ret; } //普通函数 int MyPlus(int a,char b){ int ret = a + b; return ret; } void test02(){ int a = 10; char b = 'a'; //调用函数模板,严格匹配类型 MyPlus(a, a); MyPlus(b, b); //调用普通函数 MyPlus(a, b); //调用普通函数 普通函数可以隐式类型转换 MyPlus(b, a); //结论: //函数模板不允许自动类型转换,必须严格匹配类型 //普通函数可以进行自动类型转换 }
函数模板和普通函数 都识别 优先选择普通函数
/函数模板和普通函数 都识别 如果选择函数模板 加<>
三、类模板类模板和函数模板的定义和使用类似,我们已经进行了介绍。有时,有两个或多个 类,其功能是相同的,仅仅是数据类型不同。 类模板用于实现类所需数据的类型参数化
template类模板做函数参数:class Person { public: Person(NameType name, AgeType age) { this->mName = name; this->mAge = age; } void showPerson() { cout << "name: " << this->mName << " age: " << this->mAge < < endl; } public: NameType mName; AgeType mAge; }; void test01() { //Person P1("德玛西亚",18); // 类模板不能进行类型自动推导 Person P1("德玛西亚", 18); P1.showPerson(); }
template类模板派生普通类class Person{ public: Person(NameType name, AgeType age){ this->mName = name; this->mAge = age; } void PrintPerson(){ cout << "Name:" << this->mName << " Age:" << this->mAge << endl; } public: NameType mName; AgeType mAge; }; //类模板做函数参数 void DoBussiness(Person & p){ p.mAge += 20; p.mName += "_vip"; p.PrintPerson(); } int main(){ Person p("John", 30); DoBussiness(p); system("pause"); return EXIT_SUCCESS; }
//类模板 template类模板派生类模板class MyClass{ public: MyClass(T property){ this->mProperty = property; } public: T mProperty; }; //子类实例化的时候需要具体化的父类,子类需要知道父类的具体类型是什么样的 //这样 c++编译器才能知道给子类分配多少内存 //普通派生类 class SubClass : public MyClass { public: SubClass(int b) : MyClass (20){ this->mB = b; } public: int mB; };
//父类类模板 template类模板类内实现class base { T m; }; template class Child2 : public base //继承类模板的时候,必须要确定基类的大 小 { public: T mParam; }; void test02() { Child2 d2; }
templateclass Person { public: Person(NameType name, AgeType age) { this->mName = name; this->mAge = age; } void showPerson() { cout << "name: " << this->mName << " age: " << this->mAge < < endl; } public: NameType mName; AgeType mAge; }; void test01() { //Person P1("德玛西亚",18); // 类模板不能进行类型自动推导 Person P1("德玛西亚", 18); P1.showPerson(); }



