c++用模板实现泛型,关键字是 template 相当于其他语言的泛型
函数模板
模板当调用的时候要给出明确类型,然后编译器根据类型生成多个不同的函数定义,例如调用了3次,不同的3个类型,那么编译器就在汇编的时候call了3个不同的函数地址,都是不同的类型函数定义
格式 template
或者 template
typename 和 class 可以互换,完全等价
template <typename T>
template <class T>
多个不同的类型,要单独为每个类型设置一个 typename,如下:
template <typename T1,typename T2>//每个类型单独用typename 修饰类型
void show(T1 a,T2 b)
代码示例
xcode版本
using namespace::std;
template <typename T>
T add(T a, T b){
return a + b;
}
/*
多参数模板
*/
template <typename T1,typename T2>//每个类型单独用typename 修饰类型
void show(T1 a,T2 b){
cout << a <<endl <<b<<endl;
}
class Person{
public:
int age = 0;
Person(int a):age(a){}
Person operator + (Person & person){ //重载了+ ,供 add函数使用
return Person(this->age + person.age);
}
};
int main(int argc, const char * argv[]) {
/*
模板的调用的时候,完整调用要加上<类型>,给出明确类型,但是如果,类型在括号里能自动识别出来,就不需要加<类型>
*/
cout<< add<int>(1,2)<<endl;
cout << add(3,4)<<endl;//类型刚好在()里面自动能识别出来是int类型
cout << add(3.11,4.11)<<endl;//类型自动识别成 float类型
cout << sub(1,2)<<endl;
Person a = Person(3);
Person b = Person(10);
cout << add(a,b).age <<endl; //add传入自定义的类对象,需要在类里面有可以被调用的操作符,重载+,因为add里面重载了 + 加号
show(3, 3.14);
show("abc", 789);
}
vc++版本重载<<操作符,类里面的 重载 <<要在前面加上template,类外面重载操作符要把<<改成 <<<>
#include <iostream>
using namespace std;
template <typename T>
class Person {
T age;
public:
Person(T a):age(a){}
template <typename T>
friend ostream& operator <<(ostream& cout, Person<T>& person);
};
template <typename T>
ostream& operator <<<>(ostream& cout, Person<T>& person) {//xcode下写 <<就行 但是在VS.net平台下, 要把 <<写成 <<<> ostream &operator <<<> (ostream &cout,Person<T> & person){
cout << "age = " << person.age;
return cout;
}
int main()
{
Person<int> a = Person<int>(3);
cout << a << endl;
}
类模板
- 类模板跟函数模板一样,只是放在类的开头
- 类外定义函数,如果函数包括泛型,需要写template 和类型,并且在类名后面添加泛型类型 ,例如:
template <typename T>
void Person<T>::setAge(T age)
代码示例
template <typename T>
class Person{
T age;
public:
friend ostream &operator << (ostream &cout,Person<T> & person);
Person(T a):age(a){}
Person operator + (Person & person){ //重载了+ ,供 add函数使用
return Person(this->age + person.age);
}
void setAge(T age);
};
//类外定义函数,如果函数包括泛型,需要写template <typename T> ,并且在类名后面添加<T>::
template <typename T>
void Person<T>::setAge(T age){
age = age;
cout << "setAge() = "<< age <<endl;
}
template <typename T>
ostream &operator << (ostream &cout,Person<T> & person){//xcode下写 <<就行 但是在VS.net平台下, 要把 <<写成 <<<>
cout <<"age = " << person.age;
return cout;
}
int main(int argc, const char * argv[]) {
Person<int> a = Person<int>(3); //创建对象的时候要给出泛型的明确类型
Person<int> b = Person<int>(10);
a = a + b;
Person<int> c = a+b;//调用重载的+运算符
cout << c <<endl; //调用重载的 << 运算符
a.setAge(33);
}