📜  重载子例程的调用以及在C++中查找精确匹配的方法

📅  最后修改于: 2021-05-30 18:23:42             🧑  作者: Mango

就像其他子例程一样,重载子例程也被调用。要确定要调用哪个函数,重要的是确定参数的数量和类型。例如,下面的代码部分将介绍调用重载子例程:

prnsqr('z')                   // calls #2
prnsqr(13)                    // calls #1
prnsqr(134.520000012)         // calls #4
prnsqr(12.5F)                 // calls #3

当函数调用最初与可用的原型以及给定的参数的数字和类型匹配时,将调用适当的函数以执行。

在float,double值或int或long值之间,可能存在歧义,例如以下声明所调用的函数:

void prnsqr(double d);

值为1.24,可以假定为float或double。常量后缀(F,U,L,UL)等用于避免歧义,这些值有助于说明要调用哪个重载子例程。普通的浮点常量(312.32)是双精度型,后缀F(312.32 F)是浮点型,L(312.32 L)使其长双精度型。对于整数,不带后缀的常量是有符号的int值。 U后缀为无符号常量,L后缀为long,LU或UL后缀为unsigned long。这些后缀可以用小写或大写字母书写。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
  
class Distance {
private:
    int centimeter;
    int kilometer;
  
public:
    // Default Constructors
    Distance()
    {
        centimeter = 0;
        kilometer = 0;
    }
  
    // Parameterized Constructors
    Distance(int cm, int km)
    {
        centimeter = cm;
        kilometer = km;
    }
  
    // Overload function call
    Distance operator()(int a,
                        int b, int c)
    {
        Distance D;
        D.centimeter = a + c + 10;
        D.kilometer = b + c + 100;
        return D;
    }
  
    // To display distance
    void displayDistance()
    {
        cout << "centimeter: "
             << centimeter
             << "kilometer:"
             << kilometer << '\n';
    }
};
  
// Driver Code
int main()
{
    Distance D1(87, 33), D2;
  
    cout << "First Distance : ";
    D1.displayDistance();
  
    // Invoke operator()
    D2 = D1(10, 10, 10);
    cout << "Second Distance :";
  
    D2.displayDistance();
  
    return 0;
}


C++
// C++ program for the above approach
  
#include 
using namespace std;
  
// Function for integer parameter
void afunc(int h)
{
    cout << "Integer:" << h;
}
  
// Function for double parameter
void afunc(double d)
{
    cout << "double:" << d;
}
  
// Driver code
int main()
{
    afunc(0);
    return 0;
}


C++
// C++ program for the above approach
#include 
using namespace std;
  
// Function for integer parameter
void value(int s)
{
    cout << "Integer:" << s;
}
  
// Function for character parameter
void value(char* b)
{
    cout << "Char:" << b;
}
  
// Driver Code
int main()
{
    char st = 'd';
    value(st);
    return 0;
}


C++
// C++ program to explain the standard
// conversion rule
#include 
using namespace std;
  
// Driver Code
int main()
{
    // integer h
    int h = 11;
  
    // character c
    char s = 'a';
  
    // s implicitly converted
    // to int. ASCII value of
    // 'a' is 97
    h = h + s;
  
    // h is implicitly converted
    // to float
    float f = h + 1.0;
  
    cout << "h = " << h << endl
         << "s = " << s << endl
         << "f = " << f << endl;
  
    return 0;
}


C++
// C++ program to illustrate the user
// defined type casting
#include 
using namespace std;
  
// Driver Code
int main()
{
    double h = 1.4;
  
    // Explicit conversion
    // from double to int
    int add = (int)h + 2;
  
    cout << "Add = " << add;
    return 0;
}


输出:
First Distance : centimeter: 87kilometer:33
Second Distance :centimeter: 30kilometer:120

找到准确匹配的方法:

通过一个实例实例,通过称为参数匹配的过程(也称为歧义消除过程),通过一个函数实例来解决该重载子例程的调用。以下是3种可能的情况,可能会导致函数调用:

  1. 匹配:发现用于函数调用。
  2. 不匹配:用于函数调用。
  3. 模糊匹配:不只一个描述的实例匹配。

编译器将尝试为函数调用找到最佳匹配。

编译器进行匹配的步骤

  • 搜索完全匹配:当实际参数类型与一个已定义实例的类型完全匹配时,编译器将为该实例调用。举些例子:
    // For overloaded functions
    void afunc(int);
    void afunc(double);    
    
    // For exact match. Match afunc(int)
    afunc(0);
    

    0(零)是int类型,将afunc(int)与call匹配。

    以下是相同的程序:

    C++

    // C++ program for the above approach
      
    #include 
    using namespace std;
      
    // Function for integer parameter
    void afunc(int h)
    {
        cout << "Integer:" << h;
    }
      
    // Function for double parameter
    void afunc(double d)
    {
        cout << "double:" << d;
    }
      
    // Driver code
    int main()
    {
        afunc(0);
        return 0;
    }
    
    输出:
    Integer:0
    
  • 通过提升匹配:如果未找到完全匹配,则编译器将尝试通过提升实际参数来获取匹配。如果所有值都不能用int表示,并且将整数类型转换为(char,short,enumerator,int)或无符号int,则称为整数提升。现在,我们将看到以下代码部分:

    以下是相同的程序:

    C++

    // C++ program for the above approach
    #include 
    using namespace std;
      
    // Function for integer parameter
    void value(int s)
    {
        cout << "Integer:" << s;
    }
      
    // Function for character parameter
    void value(char* b)
    {
        cout << "Char:" << b;
    }
      
    // Driver Code
    int main()
    {
        char st = 'd';
        value(st);
        return 0;
    }
    
    输出:
    Integer:100
    
  • 通过应用标准C++转换规则,找到了一个匹配项:如果未找到完全匹配项或通过提升找到匹配项,则尝试通过实际参数的标准转换来实现匹配项。下面是相同的示例:

    使用C++标准转换规则,可以将int参数471转换为双精度471,并且如果实际参数可以转换为多种形式参数类型,则编译器将生成错误消息,因为它是模棱两可的匹配项。例如:

    void afunc(long)
    void afunc(double)
    
    // Error will generate as ambiguous match
    afunc(15)
    

    将int参数15转换为long或double会产生关于使用afunc()的模棱两可的情况。

    以下是相同的程序:

    C++

    // C++ program to explain the standard
    // conversion rule
    #include 
    using namespace std;
      
    // Driver Code
    int main()
    {
        // integer h
        int h = 11;
      
        // character c
        char s = 'a';
      
        // s implicitly converted
        // to int. ASCII value of
        // 'a' is 97
        h = h + s;
      
        // h is implicitly converted
        // to float
        float f = h + 1.0;
      
        cout << "h = " << h << endl
             << "s = " << s << endl
             << "f = " << f << endl;
      
        return 0;
    }
    
    输出:
    h = 108
    s = a
    f = 109
    

    注意:如果未看到升级,则编译器将通过标准转换找到匹配项。任何数字类型都与另一个数字类型(包括无符号)(例如int和float)匹配。枚举将与数字类型的形式类型匹配(例如,浮点枚举)。 0必须与指针类型和数字类型相匹配(例如,将0表示为char *,将0表示为浮点数)。虽然Pointer与void指针匹配。

  • 通过应用用户定义转换来找到匹配项:如果上述所有步骤均失败,则编译器将结合使用用户定义的转换,积分提升和内置转换来查找唯一的匹配项。在给定的C++中,任何函数(无论是类成员还是普通函数)都可以在C++中重载,以适用于不同的参数类型数字和组合。

    以下是相同的程序:

    C++

    // C++ program to illustrate the user
    // defined type casting
    #include 
    using namespace std;
      
    // Driver Code
    int main()
    {
        double h = 1.4;
      
        // Explicit conversion
        // from double to int
        int add = (int)h + 2;
      
        cout << "Add = " << add;
        return 0;
    }
    
    输出:
    Add = 3
    
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”