前言
C++提供了函数模板(function template)。所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需在模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。
总结:
-
模板把函数或类要处理的数据类型参数化,表现为参数的多态性,称为类属。
-
模板用于表达逻辑结构相同,但具体数据元素类型不同的数据对象的通用行为。
1.所有的类模板都写在类的内部
demo1(编译通过)
#include <iostream>
#include <string>
using namespace std;
template <typename T>
class Complex{
friend ostream & operator <<(ostream &out,Complex &c3){
out<<c3.a<<"+"<<c3.b<<"i"<<endl;
return out;
}
public:
Complex (T a,T b){
this->a=a;
this->b=b;
}
Complex operator+ (Complex &c2){
Complex tmp(a+c2.a,b+c2.b);
return tmp;
}
void PrintTmp(){
cout<<"a:"<<a<<"b:"<<b<<endl;
}
private:
int a,b;
};
int main(int argc, char *argv[])
{
Complex<int> a(2,3);
Complex<int> b(3,4);
Complex<int> c3=a+b;
c3.PrintTmp();
cout<<c3<<endl; //重载左移运算符
cout << "Hello World!" << endl;
return 0;
}
2.所有的类模板都写在类的内部,在一个cpp 中
//1.构造函数没有问题和一般正常操作即可
//2.普通函数没有问题,正常操作
//3.友元函数的:
(1)重载<< >>
friend ostream& operator<< <T>(ostream& out, const AA<T>& tmp);
(2)非重载《》具体套路步骤:
(1)需要在类前增加类的前置声明
temnplate <class T>
class AA;
template <class T>
AA<T> mySU币(AA<T>& c1, AA<T>& c2);
(2)类的内部声明:
friend AA <T> mysub <T> (AA<T>&c1,AA <T>& c2);
(3)友元函数实现必须写成:
template<class T>
AA<T> mysub(AA<T>&c1,AA<T>&c2)
{
AA<T> tmp(c1.a-c2.a,c1.b-c2.b);
return tmp;
}
(4)友元函数的调用
AA <int> c4=mySub<int>(c1,c2);
cout<<c4;
demo2:
#include <iostream>
using namespace std;
/***************特别注意!!!!***********************/
/**********这里一定要声明*** 不加声名一定会报错***********/
template <class T>
class AA;
template <class T>
ostream& operator <<(ostream&,const AA<T>& tmp);
template <class T>
class AA{
public:
AA(T a,T b);
void printAA();
AA operator+(AA &tmp);
//友元函数重载
// friend ostream& operator << <T>(ostream &out,AA<T> & tmp);
friend ostream& operator<< <T>(ostream& out, const AA<T>& tmp);
public:
T a ;
T b;
};
/*在类外实现各个函数*/
template <class T>
AA<T>::AA(T a,T b){
this->a=a;
this->b=b;
}
template <class T>
void AA<T>::printAA(){
cout<<"a:"<<a<< " "<< "b:"<<b<<endl;
}
template <class T>
AA<T> AA<T>::operator +(AA<T> &tmp){
AA tt(this->a+tmp.a,this->b+tmp.b);
return tt;
}
//友元函数实现重载
//友元函数重载<<
template <typename T>
ostream& operator<< (ostream& out, AA<T>& tmp)
{
out << "a=" << tmp.a << " b=" << tmp.b << endl;
return out;
}
int main(int argc, char *argv[])
{
AA<int> tmp1(5,6);
AA<int> tmp2(6,7);
AA<int> tmp3=tmp1+tmp2;
tmp3.printAA();
cout << tmp3 << endl;
cout << "Hello World!" << endl;
return 0;
}
3.所有的类模板函数写在类的外部,在不同的.h 和.cpp 中
In brief:
就是类模板函数说明与类模板实现分开
/*******complex.h文件:*******************************/
#pragma once
#include <iostream>
using namespace std;
template <class T>
class Complex;
template <class T>
ostream& operator<<(ostream& out,Complex<T>& c3);
template <class T>
class Complex{
friend ostream& operator<< <T>(ostream& out,Complex<T>& c3);
public:
Complex(T a, T b);
void pringCom();
Complex operator+(Complex &c2);
private:
T a;
T b;
};
/********************complex.cpp********************/
#include <iostream>
#include "complex.h"
using namespace std;
template <class T>
Complex<T>::Complex(T a,T b){
this->a=a;
this->b=b;
}
template<class T>
void Complex<T>::pringCom(){
cout<<"a:"<<a<<"b:"<<b<<endl;
}
/*成员函数实现加号的重载*/
template<class T>
Complex<T> Complex<T>::operator +(Complex<T>& c2){
Complex<T> tmp(a+c2.a,b+c2.b);
return tmp;
}
template<class T>
ostream& operator <<(ostream& out,Complex<T>& tmp){
out<<"a:"<<tmp.a<<"b"<<tmp.b<<endl;
return out;
}
/******************main.cpp************************/
#include <iostream>
#include "complex.h"
#include "complex.cpp"
using namespace std;
/*
所有的类模板函数写在类的外部,在不同的文件中实现
*/
int main()
{
Complex<int> tmp1(2,3);
Complex<int> tmp2(3,4);
Complex<int> tmp3=tmp1+tmp2;
tmp3.pringCom();
cout<<tmp3;
return 0;
}