• C++ 如何判断所调用的重载函数


    函数重载是C++的一个重要特性,但是函数重载后调用哪一个函数往往令人很困惑,参照《C++ Primer》第七章的内容总结如下:



     重载确定函数调用的步骤
    1、候选函数(candidate function)
       1)、仅当形参是引用或指针时,形参是否为const 才有影响
       2)、不能基于指针本身是否为const 来实现函数重载
       3)、return 的类型不能用于判断重载

     2、可行函数
       1)、函数形参个数匹配(默认参数也是实参)
       2)、类型匹配,包含隐式转换的匹配
    3、寻找最佳匹配
      1)、精确类型匹配 > 需要转换的匹配
      2)、通过类型提升的转换 > 其他标准转换


    我还是喜欢用实际的例子来说明问题:

      1 #include <iostream>
      2 #include <cstdlib>
      3 
      4 /*=================================================================*\
      5  *           
      6  *              重载确定函数调用的步骤
      7  *
      8  *                2013/6/5 by 樊列龙
      9  *
     10 \*=================================================================*/
     11 
     12 /*
     13  * 重载确定函数调用的步骤
     14  * 1、候选函数(candidate function)
     15  *      1)、仅当形参是引用或指针时,形参是否为const 才有影响
     16  *      2)、不能基于指针本身是否为const 来实现函数重载
     17  *      3)、return 的类型不能用于判断重载
     18  * 2、可行函数
     19  *      1)、函数形参个数匹配(默认参数也是实参)
     20  *      2)、类型匹配,包含隐式转换的匹配
     21  * 3、寻找最佳匹配
     22  *      1)、精确类型匹配 > 需要转换的匹配
     23  *      2)、通过类型提升的转换 > 其他标准转换
     24  */
     25 
     26 using namespace std;
     27 
     28 
     29 ////////////////////////////////////////////////////
     30 void funA(int &a, int &b)
     31 {
     32     cout << "调用:funA(int &a, int &b)" << endl;
     33 }
     34 
     35 void funA(const int &a, const int &b)
     36 {
     37     cout << "调用:funA(const int &a, const int &b)" << endl;
     38 }
     39 
     40 
     41 ////////////////////////////////////////////////////
     42 void funB(int *a, int *b)
     43 {
     44     cout << "调用:funB(int *a, int *b)" << endl;
     45 }
     46 void funB(const int *a, const int *b)
     47 {
     48     cout << "调用:funB(const int *a, const int *b)" << endl;
     49 }
     50 
     51 ////////////////////////////////////////////////////
     52 void f()
     53 {
     54     cout << "调用:void f()" << endl;
     55 }
     56 
     57 void f(int )
     58 {
     59     cout << "调用:void f(int )" << endl;
     60 }
     61 
     62 void f(int , int i = 1 )
     63 {
     64     cout << "调用:void f(int , int )" << endl;
     65 }
     66 
     67 void f(double, double d = 1.0)
     68 {
     69     cout << "调用:void f(double, double)" << endl;
     70 }
     71 
     72 
     73 ///////////////////////////////////////////////////
     74 void ff(short)
     75 {
     76     cout << "调用:void ff(short)" << endl;
     77 }
     78 void ff(int)
     79 {
     80     cout << "调用:void ff(int)" << endl;
     81 }
     82 
     83 ///////////////////////////////////////////////////
     84 void fff(long)
     85 {
     86     cout << "调用:void fff(long)" << endl;
     87 }
     88 void fff(float)
     89 {
     90     cout << "调用:void fff(float)" << endl;
     91 }
     92 
     93 int main()
     94 {
     95     int a, b;
     96     const int ca = 0;
     97     const int cb = 0;
     98 
     99     funA(a,b);     // 调用:funA(int &a, int &b)
    100     funA(a,cb);    // 调用:funA(const int &a, const int &b)
    101     funA(ca,cb);   // 调用:funA(const int &a, const int &b)
    102 
    103     funB(&a,&b);   // 调用:funB(int *a, int *b)
    104     funB(&ca,&cb); // 调用:funB(const int *a, const int *b)
    105     funB(&a,&cb);  // 调用:funB(const int *a, const int *b)
    106     
    107 
    108     f(5.6);        // 调用:void f(double, double)
    109     //f(5);          // Error: 调用重载的‘f(int)’有歧义
    110     //f(5,6.0);      // 错误:调用重载的‘f(int, double)’有歧义
    111     f(static_cast<double>(5),6.0);// 调用:void f(double, double)
    112     f(5,static_cast<int>(6.0));   // 调用:void f(int , int )
    113     
    114 
    115     cout << "sizeof(short): " << sizeof(short) << endl;
    116     cout << "sizeof(char): " << sizeof(char) << endl;
    117 
    118     ff('a');                      // 调用:void ff(int)
    119 
    120     //double 既可以转换为long 也可以转换为 float,有二义性
    121     //fff(3.14);                    // 错误:调用重载的‘fff(double)’有歧义
    122     
    123     return EXIT_SUCCESS;
    124 }

    执行结果:

     1 调用:funA(int &a, int &b)
     2 调用:funA(const int &a, const int &b)
     3 调用:funA(const int &a, const int &b)
     4 调用:funB(int *a, int *b)
     5 调用:funB(const int *a, const int *b)
     6 调用:funB(const int *a, const int *b)
     7 调用:void f(double, double)
     8 调用:void f(double, double)
     9 调用:void f(int , int )
    10 sizeof(short): 2
    11 sizeof(char): 1
    12 调用:void ff(int)
    View Code
  • 相关阅读:
    Nebula3的Input系统
    Nebula3学习笔记(7): 脚本系统
    项目经理成长日记(4)——态度决定一切
    Nebula3学习笔记(2): 核心库
    Nebula3学习笔记(1): 序
    魔兽争霸的地图验证漏洞和作弊图原理,兼谈魔兽联机机制[转载]
    Nebula3的多线程架构
    项目经理成长日记(5)——五指有长短,能力各不同
    Nebula3资源子系统
    Nebula3的场景管理
  • 原文地址:https://www.cnblogs.com/CocoonFan/p/3118240.html
Copyright © 2020-2023  润新知