• C++ 重载函数


    1、什么是重载函数

      同一个函数名定义不同的函数,当函数名相同,不同的参数搭配时含义不同。

      例如:

      

    #include <stdio.h>
    #include <string.h>
    
    
    int func(int x)
    {
        return x;
    }
    
    int func(int x,int y)
    {
        return x + y;
    }
    
    int func(const char *s)
    {
        return strlen(s);
    }
    
    
    
    int main(int argc, char *argv[])
    {
        printf("Begin...
    ");
        printf("%d
    " ,func(1));
        printf("%d
    " ,func(2,3));
        printf("%d
    " ,func("abcdefg"));
        printf("End...
    ");
        return 0;
    }

      运行结果:

    Begin...
    1
    5
    7
    End...

      上面代码函数名相同,在C语言中是肯定会报错的因为C语言不支持重载函数。而在C++中是不会报错的。而且会根据参数 调用 对应的函数。

    2、允许重载的条件是什么了?

      2.1、参数类型不同

      2.2、参数个数不同

      2.3、参数顺序不同

      三个条件满足其中一条即可满足重载。

      例如:下面代码中的两个 func 就满足第 2.3条 参数顺序不同  

    #include <stdio.h>
    #include <string.h>
    
    int func(const char *s ,int a)
    {
        return a;
    }
    
    int func(int a,const char *s )
    {
        return strlen(s);
    }
    
    
    int main(int argc, char *argv[])
    {
        printf("Begin...
    ");
        printf("%d
    ",func("abc",2));
        printf("%d
    ",func(2,"abc"));
            printf("End...
    ");
            return 0;
    }

      运行结果:

    Begin...
    2
    3
    End...

    3、编译器调用重载的准则:

      3.1、将所有同名的函数作为候选

      3.2、尝试寻找可行的候选参数

        3.2.1、精确匹配实参

        3.2.2、通过默认参数能够匹配实参

        3.2.3、通过默认类型转换匹配实参

    匹配失败的原因:

      1、最终找出来的候选函数不唯一,出现二义性,编译失败。

      例如:这里调用 printf("%d " func(1,2)); 的时候 就有两个条件可以匹配所以编译器也不知道应该调用那个函数。

    #include <stdio.h>
    #include <string.h>
    
    int func(int a,int b)
    {
        return a + b;
    }
    
    int func(int a,int b,int c=10)
    {
        return a+b+c;
    }
    
    
    int main(int argc, char *argv[])
    {
        printf("Begin...
    ");
        printf("%d
    " func(1,2));
            printf("End...
    ");
            return 0;
    }

     编译结果: 

    test.cpp:18:25: error: call of overloaded ‘func(int, int)’ is ambiguous
      printf("%d
    " ,func(1,2));
                             ^
    test.cpp:4:5: note: candidate: int func(int, int)
     int func(int a,int b)
         ^~~~
    test.cpp:9:5: note: candidate: int func(int, int, int)
     int func(int a,int b,int c=10)
         ^~~~

      2、无法匹配所有候选者,函数未定义,编译失败

    4、函数重载的注意事项。

      4.1、重载函数在本质上是相互独立的函数

      4.2、重载函数的函数类型不同

      4.3、函数返回值不能作为函数重载的依据

     函数重载是由函数名 和参数列表决定的。    

    5、重载与指针。

      如下代码:

    #include <stdio.h>
    #include <string.h>
    
    int func(int a,int b)
    {
        return a + b;
    }
    
    int func(int a,int b,int c=10)
    {
        return a+b+c;
    }
    
    int func(const char *s)
    {
        return strlen(s);
    }    
    
    typedef int (*Pfunc) (int a,int b);
    
    int main(int argc, char *argv[])
    {
        printf("Begin...
    ");
        Pfunc P= func;
        int c = 0;
        c = P(1,2);
        printf("c = %d
    ",c);
        printf("End...
    ");
        return 0;
    }

      运行结果:

    Begin...
    c = 3
    End...

      通过运行结果 可以清楚的看出, c = P(1,2);    其实就是调用到  int func(int a,int b)    这个函数。

      使用  typedef int (*Pfunc) (int a,int b);  定义了一个 函数指针。

      随后通过  Pfunc P= func;   对函数指针 P进行初始化。

      调用 c = P(1,2); 

      在这个过程中 C++通过   typedef int (*Pfunc) (int a,int b);  定义的类型使得 Pfunc P= func; 这个初始化能够正确的匹配到  int func(int a,int b)   这个函数。

      最终调用到 int func(int a,int b)   这个函数。

      所以将重载函数名赋值给函数指针的时候

        1、根据重载规则挑选与函数参数列表一致的候选者。

        2、严格匹配候选者的函数类型与指针的函数类型。

      上面说过 函数的 重载 与 返回值  无关,但是在通过函数指针指向重载函数的时候,C++会将返回值也作为编译器判断语法是否错误的依据。(这里就对应了上面第二点说的严格匹配候选者,包括匹配 返回值、函数名、函数参数)

      注意:

      1、只有在同一个作用域中函数才能重载。

      2、编译器选择函数的 依据是 函数列表 函数参数

      3、无法通过函数名直接得到重载函数的入口地址。(可以通过强制类型转换的到函数的入口地址,需要给编译器提供足够多的信息选择到对应函数)

        例如:printf("%p ",(int(*)(int,int))func);   

  • 相关阅读:
    laravel 汇总数据
    Sway
    利用 Windows API Code Pack 修改音乐的 ID3 信息
    Windows Server 2012 R2 设置 NTP 服务
    Visual Studio "14" CTPs
    Win8.1 查看 “Windows 体验指数“
    json2csharp & json 格式化
    山寨版 WP8.1 Cortana 启动 PC
    Newtonsoft.Json WindowPhone7.1
    Cisco交换机基础命令 + Win Server08 R2 多网卡配置链路聚合
  • 原文地址:https://www.cnblogs.com/hjxzjp/p/11595106.html
Copyright © 2020-2023  润新知