目录
一:函数重载(静态绑定)
在编译时就知道运行哪个函数
#include<iostream>
using namespace std;
int maxNum(int a,int b) //int_maxNum_int_int
{
cout<<"demo1"<<endl;
return a>b?a:b;//三目运算符
}
double maxNum(double a,double b) //double_maxNum_double_double
{
cout<<"demo2"<<endl;
return a>b?a:b;//三目运算符
}
int maxNum(double a,int b)
{
cout<<"demo3"<<endl;
return a>b?a:b;//三目运算符
}
int main()
{
//编译时已经确定调用的函数 静态绑定
cout<<"max:"<<maxNum(10,20)<<endl;
cout<<"max:"<<maxNum(10.5,2.3)<<endl;
cout<<"max:"<<maxNum(10.5,2)<<endl;
//demo1
//max:20
//demo2
//max:10.5
//demo3
//max:10
return 0;
}
二:宏定义(不检查数据类型)
代码示例如下
#include<iostream>
using namespace std;
#define MAX(a,b)((a)>(b)?(a):(b)) //宏定义 不检查数据类型
int main()
{
cout<<"max:"<<MAX(2,3)<<endl;//max:3
cout<<"max:"<<MAX(2,5.8)<<endl;//max:5.8
cout<<"max:"<<MAX('a',10)<<endl;//max:97
return 0;
}
小结:
- 函数重载 检查变量类型 根据实际参数类型写很多个函数
- 宏定义 求最大值 不检查数据类型
- 模板 解决以上缺陷
三:模板
a.模板(一种数据类型T):
#include<iostream>
using namespace std;
template<typename T> //typename或class都可以 T数据类型
T Max(T a,T b)
{
return a>b?a:b;
}
int main()
{
//函数模板的使用 Max<具体数据类型>(实参);
cout<<"max:"<<Max<int>(10,20)<<endl;//max:20
return 0;
}
b. 模板(两种数据类型T T1):
#include<iostream>
using namespace std;
template<typename T,typename T1> //T T1两种不同的数据类型
void SWAP(T &a,T1 &b)
{
T tmp;
tmp = a;
a = T(b);
b = T1(tmp);
}
int main()
{
int q=10;
double m = 2.3;
SWAP<int,double>(q,m);
cout<<"m=:"<<m<<endl;
cout<<"q=:"<<q<<endl;
// m=:10
// q=:2
return 0;
}
小结:
1. 函数模板是函数吗?答:不是函数
2. 格式:template<typename/class 参数名>
函数类型 函数名 (形参列表) {函数体}
3. 使用的格式:函数名<实际的数据类型>(实参);
4. 使用的时候编译器会用真正的数据类型来代替函数模板中的参数类型
四:通过类模板实例化一个类
通过类模板实例化一个类 再通过具体类实例化一个对象,示例如下
Test.h:
#ifndef TEST_H
#define TEST_H
//类模板声明头文件中 类模板每个成员函数都是函数模板,实现也是在头文件中
template<class T,class T1> //2种类型数据成员
class TestA
{
public:
TestA();
TestA(T a,T1 b);
T getA();
T1 getB();
private:
T a;
T1 b;
};
template<class T,class T1>//TestA<T,T1>--类名
TestA<T,T1>::TestA( )
{
this->a = 0;
this->b = 0;
}
template<class T,class T1>
TestA<T,T1>::TestA(T a,T1 b)
{
this->a = a;
this->b = b;
}
template<class T,class T1>
T TestA<T,T1>::getA()
{
return this->a;
}
template<class T,class T1>
T1 TestA<T,T1>::getB()
{
return this->b;
}
#endif
main.cpp:
#include<iostream>
using namespace std;
#include"Test.h"
int main()
{
//业务逻辑相同 数据类型不同
//通过类模板实例化一个类 在通过具体类实例化一个对象
TestA<int,double>test1(100,80.5);
cout<<"a="<<test1.getA()<<endl;
cout<<"b="<<test1.getB()<<endl;
// a=100
// b=80.5
return 0;
}
五:模板(创建一条链表)
代码示例如下
CList.h:
#ifndef CLIST_H
#define CLIST_H
template<class T>//链表的节点模板
class CNode //类名CNode<T>
{
public:
CNode();
~CNode();
T data; // 数据域
CNode<T> *pnext; //指针域
};
template<class T>
CNode<T>::CNode()
{
this->data = 0;
this->pnext = NULL;
}
template<class T>
CNode<T>::~CNode()
{
}
template<class T>
class CList //链表类 类名CList<T>
{
public:
CList();
~CList();
void push_back(T data); //尾部添加节点
int getListCount(); //获取节点个数
private:
CNode<T>* head; //链表头
int count; //节点个数
};
template<class T>
CList<T>::CList() //创建头节点
{
this->head = new CNode<T>;
this->count = 0;
}
template<class T>
CList<T>::~CList()
{
}
template<class T>
void CList<T>::push_back(T data)
{
CNode<T>* tmp = this->head;
while(tmp->pnext!=NULL)
{
tmp = tmp->pnext;
}
CNode<T>* newNode = new CNode<T>;
tmp->pnext = newNode;
newNode->data = data;
++(this->count);
}
template<class T>
int CList<T>::getListCount()
{
return this->count;
}
#endif
main.cpp:
#include<iostream>
using namespace std;
#include"Test.h"
#include"CList.h"
int main()
{
//创建一条(int数据类型的)数字链表
CList<int>* head = new CList<int>;
head->push_back(1);
head->push_back(2);
head->push_back(3);
cout<<head->getListCount()<<endl;//3
return 0;
}
六:链表实际应用
利用上面的链表模板【创建员工链表】;示例如下
CStaff.h:
#ifndef CSTAFF_H
#define CSTAFF_H
#define ADMIN 1
#define MANAGER 2
#define WAITER 3
class Staff
{
public:
Staff();
Staff(int id,char *name,char *pwd,int prole);
~Staff();
private:
int ID;
char name[20];
char pwd[20];
int role;
};
#endif
CStaff.cpp:
#include"CStaff.h"
#include<iostream>
using namespace std;
Staff::Staff()
{
}
Staff::Staff(int id,char *name,char *pwd,int prole)
{
this->ID = id;
strcpy(this->name,name);
strcpy(this->pwd,pwd);
this->role = prole;
}
Staff::~Staff()
{
}
main.cpp:
#include<iostream>
using namespace std;
#include"Test.h"
#include"CList.h"
#include"CStaff.h"
int main()
{
//创建一条员工链表
CList<Staff *> *staffList = new CList<Staff *>;
staffList->push_back(new Staff(1001,"admin","123456",ADMIN));
staffList->push_back(new Staff(1002,"manager","123456",MANAGER));
cout<<staffList->getListCount()<<endl;//2
return 0;
}
小结:
类模板:不是类
格式: template<class/typename 参数名>
class 类名{ };
类的成员函数全部都是函数模板
使用: 创建对象:类名<真正的数据类型>对象;
对象. + 函数名
七:一般类派生类模板
#ifndef TEST_H
#define TEST_H
//类模板声明头文件中 类模板每个成员函数都是函数模板 实现也是头文件中
// 一般类派生类模板
class A
{
public:
A(){this->z = 0;}
A(int z){this->z = z;}
protected:
int z;
};
template <typename T,typename T1>
class TestA;public A //类模板 继承一般类A
{
public:
TestA();
TestA(T a,T1 b,int z);
private:
T a;
T1 b;
};
template <typename T,typename T1> //类模板所有成员函数也是模板函数
TestA<T,T1>::TestA():A()
{
this->a = 10;
this->b =10;
}
template <typename T,typename T1>
TestA<T,T1>::TestA(T a,T1 b, int z):A(z)
{
this->a = a;
this->b = b;
}
八:从类模板派生出类模板
#ifndef TEST_H
#define TEST_H
//从类模板中派生出类模板
//类模板定义 模板的实现在头文件中
template <typename T,typename T1>
class Test
{
public:
Test(void);
~Test();
Test(T a,T1 b);
T getX();
T1 getY();
private:
T x;
T1 y;
};
//---------------基类模板实现---------------
//每个函数都是模板
template <typename T,typename T1>
Test<T,T1>::Test(T a,T1 b)
{
this->x= a;
this->y= b;
}
template <typename T,typename T1>
Test<T,T1>::Test(void)
{
}
template <typename T,typename T1>
Test<T,T1>::~Test(void)
{
}
template <typename T,typename T1>
T Test<T,T1>::getX
{
return this->x;
}
template <typename T,typename T1>
T1 Test<T,T1>::getY
{
return this->y;
}
//派生类模板定义
template <typename T,typename T1>
class TestB:public Test<T,T1> //继承Test
{
public:
TestB(void);
~TestB();
TestB(T a,T1 b,T c);
T getZ();
private:
T z;
};
template <typename T,typename T1>
TestB<T,T1>::TestB(T a,T1 b,T c):Test(a,b)
{
this->z =c;
}
template <typename T,typename T1>
TestB<T,T1>::TestB(void)
{
}
template <typename T,typename T1>
TestB<T,T1>::~TestB(void)
{
}
template <typename T,typename T1>
T TestB<T,T1>::getZ()
{
return this->z;
}
#endif
九:普通类D 继承 类模板TestA
#ifndef TEST_H
#define TEST_H
//普通类 D继承类模板
class D:public TestA<int , float>
{
public:
D(){this->d = 0;}
D(int a,float b,int z,int d);
protected:
int d;
private:
};
template <int , float>
D::D(int a,float b ,int z,int d):TestA(a,b,z)
{
this->d =d;
}
#endif