C++特点:(封装、继承、多态)面向对象编程、(模板)泛型编程
函数模板#include
using namespace std;
//整型交换函数
void swap(int &a, int&b){
int tmp = a;
a = b;
b = tmp;
}
//字符交换函数
void swap(char &a, char&b){
char tmp = a;
a = b;
b = tmp;
}
//函数模板 template是关键字
//class 和 typename 均可
//T 系统自动推导 或 显式指定
template
void Swap(T &a, T &b){
T tmp = a;
a = b;
b = tmp;
}
int main()
{
int a = 1, b=2;
char A = 'a', B = 'b';
//普通交换 *** 作
cout << "a=" << a << " b=" << b << endl;
swap(a,b);
cout << "a=" << a << " b=" << b << endl;
cout << "A=" << A << " B=" << B << endl;
swap(A,B);
cout << "A=" << A << " B=" << B << endl << endl;
//模板交换操作
cout << "a=" << a << " b=" << b << endl;
Swap(a,b); //自动推导T为int
cout << "a=" << a << " b=" << b << endl;
cout << "A=" << A << " B=" << B << endl;
Swap(A,B); //自动推导T为char
cout << "A=" << A << " B=" << B << endl << endl;
return 0;
}
T也可用户显式指定
int main()
{
int a = 1, b=2;
char A = 'a', B = 'b';
cout << "A=" << A << " B=" << B << endl << endl;
//模板交换操作
cout << "a=" << a << " b=" << b << endl;
Swap(a,b); //用户显式指定T为int
cout << "a=" << a << " b=" << b << endl;
cout << "A=" << A << " B=" << B << endl;
Swap(A,B); //用户显式指定T为char
cout << "A=" << A << " B=" << B << endl << endl;
return 0;
}
函数模板和普通函数的区别
调用关系
#include
using namespace std;
//整型交换函数
void Swap(int &a, int&b){
cout << "普通交换操作" << endl;
int tmp = a;
a = b;
b = tmp;
}
//函数模板 template是关键字
//class 和 typename 均可
//T 系统自动推导
template
void Swap(T &a, T &b){
cout << "模板交换操作" << endl;
T tmp = a;
a = b;
b = tmp;
}
int main()
{
int a = 1, b=2;
cout << "a=" << a << " b=" << b << endl;
//函数模板和普通模板重名时,优先选择普通函数
Swap(a,b);
cout << "a=" << a << " b=" << b << endl;
//可以通过显式操作,选择模板函数
Swap(a,b);
cout << "a=" << a << " b=" << b << endl;
return 0;
}
函数模板不能自动类型转换,普通函数可以
练习(用函数模板实现char和int的排序)
#include
#include
using namespace std;
template
void Bianli(T *A, TT B){
for(int i = 0; i < B; i++){
cout << A[i] << " ";
}
cout << endl;
}
template
void PaiXu(T *A, TT B){
for(int i = B - 1; i > 0; i--){
for(int j = 0; j < i; j++){
T max;
if(A[j]>A[j+1]){
max = A[j];
A[j] = A[j+1];
A[j+1] = max;
}
}
}
}
int main()
{
char a[] = "hello word";
int b[] = {3, 4, 2, 1, 8, 9, 10};
int charlen = strlen(a);
int intlen = sizeof(b)/sizeof(b[1]);
//模板函数实现遍历
Bianli(a, charlen);
Bianli(b, intlen);
//模板函数实现排序
PaiXu(a, charlen);
PaiXu(b, intlen);
Bianli(a, charlen);
Bianli(b, intlen);
return 0;
}
函数模板可以重载
有的数据类型在函数模板中不适用,具有局限性
#include
using namespace std;
class P{
public:
int a;
int b;
public:
P(int a, int b): a(a), b(b){};
~P(){};
//解决方法2 重载>
bool operator>(P &obj){
return this->a>obj.a? true:false;
}
};
template
T& max(T &a, T &b){
return a>b? a:b;
};
ostream& operator<<(ostream &out, P &p){
out << p.a << " " << p.b;
return out;
}
//解决方法1 具体化模板函数
#if 0
template<>
P& max(P &obj1, P &obj2){
return obj1.a>obj2.a? obj1:obj2;
}
#endif
int main()
{
int a=1, b=2;
//在普通类型上使用,可是对象比大小不适用
//解决方法1 具体化模板
//解决方法2 原因在于系统不知道>对两对象的意义,需要重载>运算符
cout << max(a,b) << endl;
P A(10, 20);
P B(100, 200);
cout << max(A, B) << endl;
return 0;
}
类模板
类模板不能进行类型的自动推导(但是最新版的QT支持)
#include
#include
using namespace std;
//类模板
template
class P{
private:
T0 name;
T1 age;
public:
P(T0 name, T1 age): name(name), age(age){}
~P(){}
void show(){
cout << "name: " << name << " 、age:" << age << endl;
}
};
int main()
{
P DM1("德玛西亚1", 100);
DM1.show();
P DM2("德玛西亚2", 100);
DM2.show();
return 0;
}
类模板作为函数的参数
#include
#include
using namespace std;
//类模板
template
class P{
friend void giveVIP(P &obj);
private:
T0 name;
T1 age;
public:
P(T0 name, T1 age): name(name), age(age){}
~P(){}
void show(){
cout << "name: " << name << " 、age:" << age << endl;
}
};
//类模板作为函数参数 必须指定类型 具体化
void giveVIP(P &obj){
obj.name += "_vip";
obj.show();
}
int main()
{
P DM1("德玛西亚1", 100);
DM1.show();
P DM2("德玛西亚2", 100);
DM2.show();
//函数输入参数被指定,也要用被同样具体化的类模板作为输入
//DM1无法被识别
giveVIP(DM2);
return 0;
}
类模板派生出普通类
类模板成员在类外实现
类模板头文件和源文件的分离问题
为了不会出错需要将.h改为包含.cpp
但一般我们都是包含头文件的,所以为了符合常规习惯可以将.cpp中的定义放在头文件中,才能引用.h,但头文件中一般不会定义,因此可以将头文件后缀改为.hpp加以区分
强化训练。。。。
C++的类型转换重新解释转换
注:仅学习总结
QT学习C++(14)_爱吃糖葫芦的大熊的博客-CSDN博客
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)