> 技术文档 > 【C++】--入门(下)

【C++】--入门(下)


前言:

在前面我们已经讲到了C++和C语言之间的关系和区别,知道了C++是为了解决C语言中的一些不足的,下面我们继续学习C++中的知识。

一、缺省参数

缺省函数的概念:

  • 缺省函数是在函数声明和定义中为某些参数指定了默认值。当调用函数的时候,如果省略了这个参数,那么编译器就会自动的使用这个默认值。如果调用的时候,给这个参数传了值,那么就按照调用的时候的值

 

     

          可以看到我们上面的代码,第一个函数调用我们没有给其值,那么其就使用其默认值,然后第        二次调用,我们给了值,那么其就按照我们给的值去调用函数。

    • 全缺省就是函数的全部形式参都给缺省值,半缺省就是函数的形参就部分给了缺省值。C++中规定了,半缺省参数必须从右边往左依次缺省,不可以间隔缺省,或者从左边开始缺省。

            

             

         fun2就是半缺省,然后我们在第二次调用fun2的时候,我们间隔了缺省,那么编译器就报错           了。

    • 函数声明定义的时候,缺省参数不能在声明和定义中同时出现,C++中规定缺省参数必须在函数的声明出给缺省值。

           在头文件单独分离成一个文件的时候,为了避免一些不必要的麻烦,我们的缺省值一般是在           函数的定义的时候给,那么此时我们的函数声明出就不要给缺省参数了。

    二、函数重载 

    在C++中,其允许在一个作用域中出现同名的函数,这种情况叫做函数重载,不过其同名也是有要求的,就是要求函数的形参不可以一样,具体为形参的个数或者形参的类型不同。

    这个在C语言中也是不支持的,我们发现在实现加法的功能中,我们还要为了不同的数据类型,但是其实现的功能是一样的,但是函数的名字是一定要不一样,不然在C语言中是会报错的。

    1、函数的参数类型不同 

     在上面的代码中,我们看到两个ADD函数,然后我们在主函数main中也调用了两次ADD,两次调用的不同就是我们传入的参数不同,所以其会根据传入的参数的不同来调用对应的函数。

     2、函数的参数个数不同

    这里我们的函数f也构成了函数重载,此时的函数重载的实现是函数的参数的个数不同,然后其会通过传入的参数来判断调用那个函数。

    不过这种情况的函数重载要注意,尽量不要和缺省参数一起出现。

    如下:

    可以看到在我们的VS中,直接报错了。

    我们看报错的信息,这是因为我们的函数调用,没办法找到要调用的函数,因为两个函数对于这个调用在逻辑上都是可以的,所以其调用就不明确。

    所以我们在使用函数的重载和缺省参数的时候,一定要注意这种情况。

    三、引用 

    1、引用的概念和定义

    引用是给已经存在的变量取一个别的名字,所以编译器是不会给引用再开辟空间的,它和其引用的变量共用一块空间。

    其语法如下:

    类型&引用别名=引用对象;

    那么在上面的引用中,b和c都是a的别名,就像我们生活中,土豆和马铃薯,番茄和西红柿这种情况,其就是名字不一样,但是指的是同一个事物。

    我们将其地址打印出来看看:

     可以看到其是使用的同一块空间的。

    2、引用的特征 

    引用在定义的时候一定要初始化

     

     一个变量可以有多个引用,这就和我们人一样,一个人可以有多个绰号这样。

    引用一旦引用了一个实体,就不能再引用其他实体

    3、引用的使用 

    我们会发现我们的引用的符号使用的是取地址符号,我们前面学习C语言的时候,有一个东西也是和我们的地址息息相关的,那就是指针了。

    其实引用和我们的指针有很多类似的地方。

    下面我们复习一下指针的几种用法:

    我们会发现我们每次进行传参数的时候,都需要借助取地址符号,那么我们的引用会有什么效果呢?

    我们传址的目的,其实主要是为了形参的改变可以导致实参的改变。

     我们可以发现,我们的引用作为参数,形参的改变会导致实参的改变。

    下面为我们的指针和引用上语法要注意的:
    指针:

    1、指针是可以不对其进行初始化的,不过这样有野指针的风险

    2、可以对指针进行赋值,比如为 NULL,或者指向其它变量或指针

    3、使用时操作变量需要解引用*,在结构体里面->才能访问成员

    引用:
    1、必须初始化,且初始化后不可以再改变

    2、无空引用,始终指向有效的对象

    3、可以直接使用名字访问

    那么我们知道了指针和引用的区别后,那种情况下使用引用,那种情况下使用指针好呢?

    使用引用好一点的情况:

    1、函数传参

    2、操作符重载

    3、返回值

    必须使用指针的情况:

    1、动态内存管理

    2、与C语言的库进行交互的时候,这是因为C语言不支持引用

    3、可选参数

    4、引用作为函数的返回值

     我们运行这个程序,其值可能会为11,但是我们会发现,其返回的值在函数结束的时候,其会有两种可能。

    1、函数的栈帧销毁,那么这个变量的空间已经释放,那么其值就不确定了

    2、函数的栈帧还存在,那么其输出的结果就会为11。

    那么这个问题如何解决呢?
    我们可以使用一个关键字:static。

    如下:

     

    那么这个关键字就改变了这个变量的生命周期,使其在函数结束后,其空间还存在。

    5、const引用

     前面我们已经了解过const这个关键字了的,其在引用这里的作用其实也是一样的,就相当于给这个引用给了限制,其不能进行改变。

    然后我们对于一个变量,其是const的,那么如果我们要去引用它,那么我们在引用的时候要在其前面加上const关键字。

    然后对于一个普通的变量,我们可以将其const。

    四、nullptr

    nullptr实际上是一个宏,其在C++中表示NULL,这是因为在C语言中我们的NULL在底层内实际上是0,在C++中实际上为(void*)0,那么其很容易和我们的整数0弄混。

    如下:

    如上面的代码,要是再C语言中,那么其就会调用第一个函数了。

    五、inline关键字 

    inline关键字的作用:用于定义内联函数

    目的是使得函数在调用的时候,其汇编的时候,使其不展开,这样可以减少函数在调用的时候的开支,提高程序的运行效率。

    下面我们在编译器上来看其和普通函数的区别:

     上面是内联函数在反汇编的情况下,可以看到其没有被展开。

    下面我们看看普通的函数:

    可以看到普通的函数会被展开很多行

    下面为inline关键字的使用要注意的:

    inline对于编译器⽽⾔只是⼀个建议,也就是说,你加了inline编译器也可以选择在调⽤的地⽅不展 开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。inline适⽤于频繁 调⽤的短⼩函数,对于递归函数,代码相对多⼀些的函数,加上inline也会被编译器忽略。

    vs编译器debug版本下⾯默认是不展开inline的,这样⽅便调试,debug版本想展开需要设置⼀下 以下两个地⽅。  

    inline不建议声明和定义分离到两个⽂件,分离会导致链接错误。因为inline被展开,就没有函数地 址,链接时会出现报错。