• C++ 函数 函数的重载 有默认参数的函数


    函数的重载

    C++允许用同一函数名定义多个函数,这些函数的参数个数和参数类型不同。这就是函数的重载(function overloading)。

    int max1(int a,int b, int c);
    double max2(double a,double b,double c);
    long  max3(long a,long b,long c);
    #include <iostream>
    using namespace std;
    int main( )
    {
            int max(int a,int b,int c);              //函数声明
             int max(int a,int b);                    //函数声明
             int a=8,b=-12,c=27;
             cout<<″max(a,b,c)=″<<max(a,b,c)<<endl;   
             cout<<″max(a,b)=″<<max(a,b)<<endl;     }
        int max(int a,int b,int c)         //求3个整数中的最大者
        {
            if(b>a) a=b;
            if(c>a) a=c;
             return a;
        }
        int max(int a,int b)               //求两个整数中的最大者
        {
            if(a>b) return a;
            else return b;
        }

    参数的个数和类型可以都不同。但不能只有函数的类型不同而参数的个数和类型相同。

    也就是说重载与否是由参数决定的,而不是返回值决定!!!

    这里引入一个概念

    函数签名:函数的名称及其参数类型组合在一起,就定义了一个唯一的特性,称为函数签名。(不包括返回类型)

    c++要求重载函数具有不同的签名。返回类型不是函数签名的一部分。

    C++ requires that overloaded functions have distinct signature.The return type is not part of a function’s signature.


    例如:

    int main()
    {
        int f(int);
        long f(int); // error C2556: “long f(int)”: 重载函数与“int f(int)”只是在返回类型上不同
        void f(int); // error C2556: “void f(int)”: 重载函数与“int f(int)”只是在返回类型上不同
        return 0;
    }

    下面介绍重载中的二义性问题:

    如果两个不同宽度的数据类型进行运算时,编译器会尽可能地在不丢失数据的情况下将它们类型统一。若float和double运算时,如果不显式地指定为float型,会自动转换成double型进行计算。一个整数类型int和一个浮点类型float运算时,如果不显式地指定为int型,C++会先将整数转换成浮点数。

    int main()
    {
        float x = 2.1f;
        float y = 2.1;   //warning C4305: “初始化”: 从“double”到“float”截断
        return 0;
    }

    上述 语句中float y=2.1 我们以为它是一个float类型,但编译器却把它认为是double(因为小数默认是double型),所以给出了警示信息,一般要定义float类型,则应该改成2.1f。

    通常编译器会按照返回类型、参数类型、参数数量区 区别调用哪个重载函数,但有时候,数据类型自动转换机制会使编译器进入死胡同。

    float fun(float a);
    double fun(double a);
    int main()
    {
        float x;
        x = fun(5.1);
        x = fun(5);   // error C2668: “fun”: 对重载函数的调用不明确
        return 0;
    }

    在这里编译器不知道应该讲x=fun(5)转换成float还是double。

     有默认参数的函数

    一般情况下,在函数调用时形参从实参那里取得值,因此实参的个数应与形参相同。C++允许在定义函数时给其中的某个或某些形式参数指定默认值,这样,当发生函数调用时,如果省略了对应位置上的实参的值时,则在执行被调函数时,以该形参的默认值进行运算。有时多次调用同一函数时用同样的实参,给形参一个默认值,这样形参就不必一定要从实参取值了。如有一函数声明
          

      float area(float r=6.5);
      area( );              //相当于area(6.5);


    如果不想使形参取此默认值,则通过实参另行给出

     area(7.5);            //形参得到的值为7.5,而不是6.5

    实参与形参的结合是从左至右顺序进行的。因此指定默认值的参数必须放在形参表列中的最右端,否则出错。例如:

    void fun1(float a,int b=0int c,char d=’a’);     //不正确
    void fun2(float a,int c,int b=0, char d=’a’);     //正确

    在使用带有默认参数的函数时有两点要注意:
    (1)如果函数的定义在函数调用之前,则应在函数定义中给出默认值。如果函数的定义在函数调用之后,则在函数调用之前需要有函数声明,此时必须在函数声明中给出默认值,在函数定义时可以不给出默认值。
    (2)一个函数不能既作为重载函数,又作为有默认参数的函数。因为当调用函数时如果少写一个参数,系统无法判定是利用重载函数还是利用默认参数的函数,出现二义性,系统无法执行。

    void fun(int);            //重载函数之一
    void fun(intint = 2);     //重载函数之二,带有默认参数
    void fun(int = 1int = 2);  //重载函数之三,带有默认参数
    fun(3);    //error: 到底调用3个重载函数中的哪个?
    fun(4,5)   //error:到底调用后面2个重载函数的哪个?

     默认参数一般在函数声明中提供。如果程序中既有函数的声明又有函数的定义时,则定义函数时不允许再定义参数的默认值。

    void  fun(int x = 0,int y = 0);
    void main() {}
    void fun(int x = 0, int y = 0) { } 
    // error C2572: “fun”: 重定义默认参数 : 参数 2
    // error C2572: “fun”: 重定义默认参数 : 参数 1

    默认值可以是全局变量、全局常量,甚至是一个函数。例如:

    int a=1int fun(int);
    int g(int x;fun(a)); //OK,允许默认值为函数

    默认值不可以是局部变量,因为默认参数的函数调用是在编译时确定的,而局部变量的位置与值在编译时均无法确定。

    例如:

    int main()
    {
        int i;
        void g(int x=i);  // error C2587: “i”: 非法将局部变量作为默认参数
        return 0;
    }
  • 相关阅读:
    本地excel/csv文件-->hive-->mysql
    Beeline连接报错:Could not open client transport with JDBC Uri: jdbc:hive2://localhost:10000/default
    软件设计——抽象工厂模式之人与肤色 c++
    软件设计——抽象工厂模式之人与肤色
    软件设计——工厂方法模式之加密算法
    用idea实现对hdfs的部分操作
    关于将hive数据仓库中数据导出到mysql的中文乱码问题
    10月份阅读笔记二
    10月份阅读笔记一
    工厂方法模式实现DES和IDEA加密算法
  • 原文地址:https://www.cnblogs.com/wkfvawl/p/10558100.html
Copyright © 2020-2023  润新知