【C++】8. 泛型编程

1. C++模板

  1. 思想:类型参数化,泛型编程,模板技术

  2. 写法:

    1. template<class T>template<typename T>//告诉编译器如果下面紧跟着的函数出现T不要报错,T是一个通用的类型
    2. void MySwap(T &a,T &b){}
    3. MySwap(1,2)//传入int a和int b后会进行自动类型推导,将T替换成int类型,以此类推
    4. MySwap<int>(a,b);显示指定类型
  3. 模板函数与普通函数的区别:在这里插入图片描述

  4. 模板函数的调用规则:

    1. 如果模板函数和普通函数重名(重载),优先调用普通函数;除非重载的普通函数没有实现体.
    2. 如果想强制调用模板,可以MySwap<>(a,b);
    3. 如果模板函数可以产生更好的匹配,那么会优先调用模板函数.

2. 模板机制

  1. 函数模板通过具体类型产生不同的函数
  2. 编译器会对函数模板进行两次编译,再申明的地方对模板代码进行编译,在调用的地方对参数替换后的代码进行编译

3. 函数模板的局限性

  1. 函数模板的局限性:无法对数组和结构体进行部分操作;如果传入了数组,数组名为地址,因此它比较的是地址,而这也不是我们所希望的操作;
  2. 解决方法:第三代具体化自定义数据类型
  3. 语法:template<> 返回值 函数名<具体类型>(参数)
    例如:
template<> bool MyCompare<Person>(Person &a,Person &b){
	if(a.age==b.age){
		return true;
	}
	return false;
}

4. 类模板

有时,有两个或多个类,其功能是相同的,仅仅是数据类型不同。
与函数模板基本一致,不同点在template下定义的是类
  1. 类模板可以有默认参数
  2. 类模板不支持自动类型推导,必须显式指定类型
  3. 类模板中的成员函数创建时机:成员函数一开始不会创建出来,而是在运行时去创建.
  4. 类模板作函数参数:
    (1)指定传入类型
void doWork(Person<string ,int> &p){//指定了类型
	p.showPerson();
}
void test01(){
	Person<string ,int> p("Tom",20);
	doWork(p);//传入的类型与doWork指定的一样 
}

(2)参数模板化
tips:使用typeid(T1).name()查看类型

template<class T1,class T2>          //函数模板
void doWork2(Person<T1,T2> &p){      //由传进的类型推导
	//typeid(T1).name()
	p.showPerson(); 
}
void test02(){
	Person<string ,int> p("Tony",18);
	doWork2(p);
}

(3) 整体类型化

template<class T>     //只做了一个类的函数模板
void doWork3(T &p){   //将Person对象整体类型化,将整体的T进行推导成Person类型
	p.showPerson();
}
void test03(){
	Person<string ,int> p("Jack",15);
	doWork3(p);
}
  1. 类模板作派生普通类
  2. 类模板类外实现成员函数:和普通的一样,加上作用域
template<class T1,class T2> 
Person<T1,T2>::Person(T1 name,T2 age){}
  1. 类模板头文件和源文件分离实现会有些问题,建议不要写到头文件里.

5.类模板碰到继承的问题

类模板的子类叫做模板类.

Base类是类模板时,比如

template<class T>
class Base{
	T age;
}

在Child类继承时必须告诉Base中的T类型,否则T无法分配内存

class Child:public Base<int>{}

6.类模板遇到友元函数

  1. 友元函数在类内实现
template<class T1, class T2>
class Person{
//1. 友元函数在类内实现
friend void PrintPerson(Person<T1, T2>& p){
	_cout_ << "Name:" << p.mName << " Age:" << p.mAge << _endl_;
}
  1. 友元函数在类外实现
    现在类内声明:friend void PrintPerson2<>(Person<T1, T2>& p);
    再在类外实现:
//友元函数类外实现  加上<>空参数列表,告诉编译去匹配函数模板
template<class T1 , class T2>
void PrintPerson2(Person<T1, T2>& p)
{
	_cout_ << "Name2:" << p.mName << " Age2:" << p.mAge << _endl_;
}

7.类模板的应用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值