C++笔记3(函数提高,模板)

本文详细介绍了C++中的函数提升,包括函数默认参数、占位参数和函数重载,强调了注意事项和实际应用。接着探讨了模板的概念,特别是函数模板的使用、注意事项、案例及与普通函数的区别。此外,还讲解了类模板的基本语法、与函数模板的区别、成员函数创建时机以及在不同场景下的应用。内容涵盖了模板的局限性和解决方法,以及类模板与继承、友元的结合使用。
摘要由CSDN通过智能技术生成

一、函数提高

1、函数默认参数

  • 在C++中,函数的形参列表中是可以有默认值的
  • 语法:返回值类型 函数名 (参数=默认值){ }
int func(int a ,int b =20;int c = 30){
return a+b+c;
}
int  main(){
//如果有自己传入的数据,就用自己的数据,如果没有,那么就用默认值
cout<<func(10)<endl;//60
cout<<func(10,30)<endl;//70
}

注意事项:

  • 如果某个位置已经有了默认参数,那么从这个位置之后的都必须有默认值(以下为错误案例)

int func2(int a = 10,int b = 20, int c){
return a+b+c;
}
  • 如果函数声明有默认参数,函数实现就不能有默认参数(以下为错误案例);声明和实现只能有一个有默认参数
int func(int a = 10,int b = 10);//函数声明
int func(int a = 20,int b = 20){
return a+b;//函数实现
}

int main(){
cout<<func(10,10)<<endl;//报错
return 0;
}

2、函数的占位参数

  • C++中函数的参数列表可以有占位参数,用来做占位,调用函数时必须填补该位置
  • 语法:返回值类型 函数名 (数据类型){ }
void func(int a, int){
cout<<"666"<<endl;
}
int main(){
func(10,10);//占位参数必须填补
return 0;
}

3、函数重载

(1)基本语法

  • 作用:函数名可以相同,提高复用性
  • 函数重载满足条件:(1)同一个作用域下(2)函数名称相同(3)函数参数类型不同,或者个数不同,或者顺序不同
  • 注意:函数的返回值不可以作为函数重载的条件——
    比如函数使用int和void

在这里插入图片描述
在这里插入图片描述

(2)注意事项

  • 引用作为重载条件

  • 函数重载碰到函数默认参数
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    为什么func(a)调用的是无const,因为int&a = a合法,而int& a = 10不合法,const int & a = 10合法;

二、模板

1、概念

  • 建立通用的模具,大大提高复用性

2、函数模板

(1)作用

  • 建立一个通用函数,其函数返回值类型和形参类型可以不具体定制,用一个虚拟的类型来代替

(2)语法

template<typename T>
函数声明或定义

解释:
在这里插入图片描述

代码演示
在这里插入图片描述
函数模板使用(如下)
在这里插入图片描述
使用模板的两种方式:自动类型推导,显示指定类型
在这里插入图片描述
在这里插入图片描述

总结
在这里插入图片描述

(3)注意事项

  • 自动类型推导,必须推导出一致的数据类型T才可以使用
    在这里插入图片描述

  • 模板必须要确定出T 的数据类型,才可以使用
    在这里插入图片描述

(4)案例–数组排序

在这里插入图片描述

#include <iostream>
using namespace std;
//排序:从大到小

//交换函数模板
template <class T>
void mySwap(T& a, T& b) {
	T temp = a;
	a = b;
	b = temp;
}
//排序算法(选择排序)
template<class T>
void mySort(T arr[], int len) {
	for (int i = 0; i < len; i++) {
		int max = i;//认定最大值的下标
		for (int j = i + 1; j < len; j++) {
			//认定的最大值比遍历出的数值要小,说明j下标的元素才是真正的最大值
			if (arr[max] < arr[j]) {
				max = j;//更新最大值的下标
			}
		}
		if (max != i) {
		//交换max和i下标的元素
			mySwap(arr[max], arr[i]);
		}
	}
}

//提供打印数组的模板
template<class T>
void printArray(T arr[],int len) {
	for (int i = 0; i < len; i++) {
		cout << arr[i] << " ";
	}
	cout << endl;
}
void test01() {
	//测试char数组
	char charArr[] = "badcfe";
	int num = sizeof(charArr) / sizeof(char);
	mySort(charArr, num);
	printArray(charArr, num);
}
void test02() {
	//测试int数组
	int intArr[] = { 7,5,1,3,9,2,4,6,8 };
	int num = sizeof(intArr) / sizeof(int);
	mySort(intArr, num);
	printArray(intArr, num);
}
int main() {
	test01();
	test02();
	return 0;
}

3、普通函数和函数模板

(1)区别

  • 普通函数调用的时候可以发生自动类型转换(称隐式类型转换)
  • 函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换
  • 如果利用显示指定类型的方式,可以发生隐式类型转换

在这里插入图片描述
隐式类型转换就是比如以下在函数中将char类型隐式转换成int类型
在这里插入图片描述
在这里插入图片描述

总结:建议使用 显示指定类型的方式,去调用函数类型模板,因为可以自己确定通用类型T

(2)调用规则

1、规则在这里插入图片描述

2、演示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结:既然提供了函数模板,最好就不要提供普通函数,不然容易出现二义性

4、模板的局限性

在这里插入图片描述
在这里插入图片描述
因此c++为了解决这种问题,提供模板的重载,可以为这些特定的类型提供具体化的模板

示例
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结:
在这里插入图片描述

5、类模板

(1)基本语法

  • 作用:建立一个通用类,类中成员数据类型可以不具体制定,用一个虚拟的类型代表

  • 语法:template<typename T> 类

  • 解释:
    在这里插入图片描述

  • 演示在这里插入图片描述
    在这里插入图片描述

  • 总结:类模板和函数模板相似,在声明模板的时候template后面加类,此类称为类模板

(2)与函数模板的区别

1、区别在这里插入图片描述
2、演示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(3)成员函数创建的时机

1、创建时机
在这里插入图片描述

2、演示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3、总结:类模板中的成员函数并不是一开始就创建的,在调用时才去创建

(4)类模板对象做函数参数

1、三种传入方式
在这里插入图片描述
2、演示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3、总结:最常用的是第一种

(5)类模板与继承

1、注意
在这里插入图片描述
2、演示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3、总结:如果父类是类模板,子类需要指定出父类中T的数据类型

(6)类模板成员函数类外实现

1、演示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2、总结:类模板中的成员函数类外实现时,需要加上模板参数列表

(7)类模板分文件编写

1、问题和解决方式
在这里插入图片描述
2、演示
(1)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(2)
在这里插入图片描述
3、总结:主流的解决方法是第二种,将类模板成员函数写到一起,并将后缀名改为 .hpp

(8)类模板与友元

在这里插入图片描述
演示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
总结:建议全局函数做类内实现,用法简单,而且编译器可以直接识别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值