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


    一、函数提高

    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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意事项:

    • 如果某个位置已经有了默认参数,那么从这个位置之后的都必须有默认值(以下为错误案例)
    
    int func2(int a = 10,int b = 20, int c){
    return a+b+c;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 如果函数声明有默认参数,函数实现就不能有默认参数(以下为错误案例);声明和实现只能有一个有默认参数
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2、函数的占位参数

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

    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>
    函数声明或定义
    
    • 1
    • 2

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

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

    总结
    在这里插入图片描述

    (3)注意事项

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

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

    (4)案例–数组排序

    在这里插入图片描述

    #include 
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    3、普通函数和函数模板

    (1)区别

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

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

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

    (2)调用规则

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

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

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

    4、模板的局限性

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

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

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

    5、类模板

    (1)基本语法

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

    • 语法:template

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

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

    • 总结:类模板和函数模板相似,在声明模板的时候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)类模板与友元

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

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

  • 相关阅读:
    ZeRO论文阅读
    Bilibili直播录制工具B站录播姬
    UE4,UE5虚幻引擎源码版下载
    乐鑫 ESP RainMaker® 系列文章
    Hadoop 集群搭建
    java swing实现抖音上的表白程序
    【云原生之Docker实战】使用Docker部署Mango个人漫画服务器
    基于SSM的网络教学(作业)管理系统
    安全加密相关概念
    Docker | 入门:原理探究
  • 原文地址:https://blog.csdn.net/weixin_60440795/article/details/125852567