当前位置:首页 > 单片机 > C语言与CPP编程
[导读]1、简单聊一聊     今天为大家推荐一首陈同学版本的《离人》,这首歌曲也是很早之前朋友向我推荐的,目前也是在作者的音乐收藏夹中,经常随机播放到,大家有时间可以听一下!     今天为大家带来重温C++的第三篇文章,作者本次计划连载大概5篇文章吧,虽然目前


1、简单聊一聊

    今天为大家推荐一首陈同学版本的《离人》,这首歌曲也是很早之前朋友向我推荐的,目前也是在作者的音乐收藏夹中,经常随机播放到,大家有时间可以听一下!

    今天为大家带来重温C++第三篇文章,作者本次计划连载大概5篇文章吧,虽然目前还有一些小伙伴没有阅读该连载文章,不过后续作者讲解到C++方面一些有趣应用的时候可以回头看看这次连载文章,对于正在学习C++的小伙伴就需要更加好好练习了。好了,下面进入今天的正题!

2、函数带默认参数

    函数带默认值算是C++里面一个比较容易理解的知识,C语言中函数没有这种使用方法,这里主要是为了后面的函数重载进行铺垫,所以这里作者简单温习一下用法和注意事项,函数带默认参数主要是说函数在定义或者声明的时候可以为函数形参指定默认的参数,后续使用可以不用传入相对应的参数使用缺省值即可,参考如下代码:

 1#include <iostream>
2using namespace std;
3/******************************************
4 * Fuction: Printf1 
5 * Author : (公众号:最后一个bug)
6 *****************************************/

7int Printf1(int a = 1 ,int b = 2)
8{
9    cout<<"Printf1 : a = "<<a<<";b = "<<b<<endl;    
10}
11
12int Printf2(int a = 1 ,int b = 2); 
13int Printf3(int a ,int b = 2); 
14/******************************************
15 * Fuction: 测试函数默认值 
16 * Author : (公众号:最后一个bug)
17 *****************************************/

18int main(int argc, char** argv) {
19
20    cout<<"Test:函数默认值 "<<endl;  
21    cout<<"----------------- "<<endl;   
22    //Printf1
23    Printf1();
24    Printf1(4);
25    Printf1(4,5);
26    //Printf2
27    cout<<"----------------- "<<endl;   
28    Printf2();
29    Printf2(4);
30    Printf2(4,5);
31    //Printf3
32    cout<<"----------------- "<<endl;   
33    //Printf3(); 需要传递第一个参数 
34    Printf3(4);
35    Printf3(4,5);
36    cout<<"--公众号:最后一个bug--"<<endl;  
37    return 0;
38}
39
40/******************************************
41 * Fuction: Printf2 
42 * Author : (公众号:最后一个bug)
43 *****************************************/

44int Printf2(int a,int b)
45{
46    cout<<"Printf2 : a = "<<a<<";b = "<<b<<endl;    
47}
48/******************************************
49 * Fuction: Printf3
50 * Author : (公众号:最后一个bug)
51 *****************************************/

52int Printf3(int a,int b)
53{
54    cout<<"Printf3 : a = "<<a<<";b = "<<b<<endl;    
55}

    其输出结果如下:

    解析一下:作者定义了三种函数带默认参数的形式,Printf1是直接在定义确定参数缺省值;Printf2是在函数声明处提供缺省值;Printf3只提供部分参数缺省值,具体使用情况参考上面的代码。

    注意事项:

    1)函数参数自左向右从第一提供缺省值的参数开始往右的参数都需要提供缺省参数;

    2)虽然缺省参数能够放在定义或者声明,尽量放在声明,如果放在定义处,定义之前均无法提供缺省参数,会存在编译不通过的情况。

      3)由于提供了缺省值,对于程序的编码也会变得更加简洁,不过注意其实际调用函数所传入的实参都是从左向右,且不会跳跃。


3、函数重载

    重载简单一点说就是同一句话在不同的语境中表达着不同的意思,比如说在C语言中一般都不允许有同名的全局函数出现,而在C++中可以根据函数的参数不同而存在相同名字的函数,这就是函数重载。下面作者简单的写个小代码,供大家参考:

 1#include <iostream>
2using namespace std;
3
4int Fuction(int a,int b);
5int Fuction(int a,int b,int c);
6float Fuction(float a,float b);
7/******************************************
8 * Fuction: 测试函数重载 
9 * Author : (公众号:最后一个bug)
10 *****************************************/

11int main(int argc, char** argv) {
12
13    cout<<"Test:函数重载"<<endl;    
14    cout<<"result1:  "<<Fuction(1,1)<<endl;
15    cout<<"result2:  "<<Fuction(1,1,1)<<endl;
16    cout<<"result3:  "<<Fuction((float)2.0,(float)5.0)<<endl;
17    cout<<"--公众号:最后一个bug--"<<endl;  
18    return 0;
19}
20int Fuction(int a,int b)
21{
22    return (a + b); 
23
24int Fuction(int a,int b,int c)
25{
26    return (a + b + c); 
27
28float Fuction(float a,float b)
29{
30    return (a * b); 
31}

    输出结果如下:

    解析一下:通过上面的程序我们大体可以知道,我们通过函数参数的差异调用相同的函数名会最终调用不同的函数实现。这种方式就非常符合我们现实的生活,比如用录音机播放音乐,通过放置不同的磁带就可以播放不同的音乐了,所以说C++语言的特性更加符合人类的思维。

    注意事项:

    1)函数重载时函数名称必须相同,其形参存在差异,比如:参数的类型,参数的个数,参数的顺序。

      2)单独的函数返回值不同不能作为重载的依据。

      3)其实函数重载仅仅只是名称相同,他们本质属于不同的函数,在编译阶段编译器能够通过函数的参数不同来进行编译处理,同时也增加代码了代码的可读性,如果无法通过名字的参数进行区分或者存在二义性,那么会导致编译错误 : 比如我们前面函数默认值的处理,如果一个函数的参数与另外一个函数的前面参数完全一直,而另一个函数其余参数都含有默认值,这样就存在二义性,编译无法通过。

    

4、运算符重载

    重载一般分为函数重载运算符重载,在我们C语言中,对于结构体这样的打包变量是不支持运算符直接进行运算的,一般对于结构体的运算我们大多采用函数的形式进行处理,然后返回最后的结构体。

    如果我们用更加统一的眼光看待的C的话,认为它仅仅只能支持基本数据类型的运算符重载。而C++语言可以重新定义这种的运算符(如“+”等)来满足我们的需求,下面作者给一个简单的小程序供大家参考:

 1#include <iostream>
2using namespace std;
3
4class Test
5
{
6private:
7    int a;
8    int b;
9
10public:
11    Test(int param1,int param2);
12    void Printf(void); 
13    friend Test operator+(Test A,Test B); //必须定义为友元 
14};
15/************************************
16 * Fuction :析构函数 
17 * Author  :(公众号:最后一个bug) 
18 ************************************/

19Test::Test(int param1,int param2)
20{
21    a = param1;
22    b = param2;
23}
24/************************************
25 * Fuction :Printf 
26 * Author  :(公众号:最后一个bug) 
27 ************************************/

28void Test::Printf(void)
29{
30    cout<<"a = "<<a<<",b = "<<b<<endl; 
31
32}
33/************************************
34 * Fuction :重载加法运算符 
35 * Author  :(公众号:最后一个bug) 
36 ************************************/

37Test operator+(Test A,Test B)
38{
39    Test Ret(0,0); 
40
41    Ret.a = A.a + B.a;
42    Ret.b = A.b + B.b;
43
44    return Ret;
45}
46
47int main(int argc, char** argv) {
48    Test stTest1(1,2);
49    Test stTest2(1,2);
50    Test stTest3(0,0);
51
52    stTest3 = stTest1 + stTest2; //直接可以进行加法运算 
53    stTest3.Printf();
54    cout<<"公众号:最后一个bug"<<endl; 
55    return 0;
56}

    最后的输出结果我就不贴图了a = 2,b = 4;

    解析一下 :

    1)其实运算符重载你可以简单的认为就是把运算符操作用operator关键字定义的对应函数来进行调用处理即可。其实和我们平时在C语言定义函数来进行结构体加法运算是一样的道理。

    2)在13行我们使用了friend关键字来进行修饰,为了让operator定义的函数内部能够访问Test类的内部私有成员,强调一点的是operator定义的函数不属于类Test,如果operator函数内部访问其Test的私有成员属于外部访问,这样是不允许的,所以我们使用了friend来为其开放访问权限;如果我们不想直接访问类Test内的私有成员,我们可以在public里面为其开放对应接口,然后在operator函数中进行调用即可。

    3)谈到第二点可能很多小伙伴会问为什么不把重载函数放到类里面来实现,这样不就可以访问其类的私有变量了吗?就可以省略friend关键字了!确实,大家可以编码进行实现,这样有一点我们得修改类,如果采用我们现在的全局方式通过调用类的public接口会更加灵活一点。

    4)这样看来我们如果还有其他的类要实现+法运算,同样需要用operator来进行定义,同一个+法运算就有多种用法了,所以叫运算符重载!


5、最后小结

    对于运算符的重载,作者仅仅举例了+法运算,还有"=,++,&&"等等,哪些运算符可以重载,怎么重载,还有一些注意事项,可能需要大家查找相关书籍或者文档进行学习,基本上大同小异,都是一些语法问题,大家依葫芦画瓢+死记硬背基本上可以搞定,其实在真正开发的过程中,一些冷门的语法是用得很少的,甚至基本上不会用,而我们学习主要是为了对这些语法不要太陌生,以后阅读某某大佬或者项目的代码遇到了可以回忆得起来,然后好好查查资料,印象就特别深刻了!

    

最近文章推荐

const关键字应用总结

Linux思维导图整理(建议收藏)

C语言C++中assert的用法

字符串操作的全面总结

代码防御性编程的十条技巧

 九种查找算法

  数据结构之堆栈

 一文轻松理解内存对齐

点【在看】是最大的支持 

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭