• 函数重载


    如果同一作用域的几个函数名相同但形参列表不同,我们称之为重载函数。这些函数接受的参数类型不同,但是执行的操作非常类似。当调用这些函数时,编译器会根据传递的实参类型推断想要的是哪个函数。函数重载可以在一定程度上减轻程序员起名字,记名字的负担。main 函数不能重载。

    不允许两个函数除了返回类型外其他所有的要素都相同:

    1 int gel(int a, int b){}
    2 
    3 char gel(int a, int b, int c){}//在参数列表不同的情况下允许返回类型不同
    4 
    5 // char gel(int a, int b){}//错误,不允许两个函数除了返回类型外其他要素都相同
    6 
    7 int gel(char a, char b){}

    判断两个形参的类型是否相异:

    有时候两个形参列表看起来不一样,但实际上是相同的:

    1 //下面每对声明的是同一个函数
    2 int gel(const int &x);
    3 int gel(const int&);//省略了形参名字
    4 
    5 typedef int phone;//phone是int的别名
    6 int lou(const phone&);
    7 int lou(const int&);

    还有前面的博客中说过,在形参中,顶层 const 是可以忽略的。这点在函数重载里面也是一样的:

     1 //这四条声明语句是两两等价的
     2 int gel(const int a);
     3 int gel(int a);
     4 
     5 int lou(int* const a);
     6 int lou(int*);
     7 
     8 //下面两条声明语句只有返回值不同,无法通过编译
     9 int ting(const int a);
    10 double ting(int a);

    调用重载函数:

    定义了一组重载函数后,我们需要以合理的实参调用它们。函数匹配是指一个过程,在这个过程中我们把函数调用与一组重载函数中的某个关联起来,函数匹配也叫重载确认。编译器首先将调用的实参与重载集合中每个函数的形参进行比较,然后根据比较的结果决定到底调用哪个函数。一般情况下这个过程是比较容易判断的,但有一些情况下比较难看出最终的选择函数。比如:当两个重载函数形参数量相同且可以相互转换时。

    调用重载函数时有三种可能的结果:

    1.编译器找到一个实参最佳匹配的函数,并生成调用该函数的代码。

    2.找不到任何一个函数与调用的实参匹配,此时编译器发出无匹配的错误信息。

    3.有多于一个函数可以匹配,但是每种都不是最佳匹配。此时也将发生错误,称为二义性错误。

    重载与作用域:

    和一般变量作用域规则一样,如果我们在内层作用域中声明名字,它将隐藏外层作用域中声明的同名实体。在不同的作用域中无法重载函数名。事实上,一般来说,将函数声明置于局部作用域内不是一个明智的选择。

    函数匹配:

    确定候选函数和可行函数:

    函数匹配的第一步是选定本次调用对应的重载函数集,集合中的函数称为候选函数。候选函数具备两个特征:一是与被调用函数同名,二是其声明在调用点可见。

    第二步考察本次调用提供的实参,然后从候选函数中选出能被这组实参调用的函数,这些新选出的函数称为可行函数。可行函数也有两个特征:一是其形参数量与本次调用提供的实参数量相等,二是每个实参的类型与对应的形参类型相同,或者能转换成形参的类型。

    注意:如果函数含有默认实参,则传入的实参数量可能少于它实际使用的实参数量。

    寻找最佳匹配:

    函数匹配的第三步是从可行函数中选择与本次调用最匹配的函数。在这一过程中,逐一检查函数调用提供的实参,寻找形参类型与实参类型最匹配的那个可行函数:

    1.该函数每个实参的匹配都不劣于其他可行函数需要的匹配。

    2.至少有一个实参的匹配优于其它任何可行函数提供的匹配。

    如果检查了所有实参之后没有任何一个函数脱颖而出,则该调用是错误的。编译器将报告二义性调用的信息。

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void gel(double x1, double x2){}
     5 
     6 void gel(int x1, int x2){}
     7 
     8 int main(void){
     9     gel(1, 1);
    10     gel(0.1, 0.1);
    11     // gel(1, 0.1);//错误调用,考虑调用第一个gel函数,1需要转换成double型,考虑调用第二个gel函数则0.1需要转换成int类型
    12     return 0;
    13 }

    实参类型转换:为了确定最佳匹配,编译器将实参类型到形参类型的转换划分成几个等级:

    1.精确匹配包括:

      a.实参类型和形参类型相同

      b.实参从数组类型或者函数类型转换成对应的指针类型

      c.向实参添加顶层 const 或者从实参中删除顶层 const

    2.通过const转换实现的匹配

    3.通过类型提升实现的匹配

    4.通过算术类型的转换或指针转换实现的匹配

    5.通过类类型转换实现的匹配

  • 相关阅读:
    如何快速搞定websocket
    websocket断网消息补发
    div嵌套多个点击事件,点击后如何阻止多次事件触发冒泡
    仿照 MediatR实现了一个中介者模式Publish功能,使用同MediatR
    git提交指南(超级详细)
    删除github中的文件夹
    抽取进程集成模式注册报错,OGG-08221,OCI Error ORA-44004 invalid qualified SQL Name
    Oracle-参数学习_no_or_expansion
    OGG19版本源端新增字段,目标端复制进程不报错,使用MAPALLCOLUMNS进行测试
    Oracle存储过程如何定位慢SQL?
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/8051891.html
Copyright © 2020-2023  润新知