• cpp中的函数重载


    函数重载可以让您使用多个同名函数,这有那些有点呢,比如我写一个加法的函数

    int add(int a.int b) {return a+b;}
    

    要是我们现在需要一个三个数的加法呢

    int add(int a.int b, int c) {return a+b+c;}
    

    这在C语言中是行不通的,因为函数重名了,但是在C++中都是可以的,因为这属于函数多态,一个加法函数就可以实现两个,三个,四个。。。数的加法,也可以实现浮点数或者整数的加法。

    函数重载的关键是函数的参数列表,也叫函数的特征标(function signature),如果两个函数的参数数目和类型相同,同时参数的排列顺序也相同,则他们的特征标相同,编译器认为是一个函数。

    参数类型不同的重载
    int add(int a, int b) {
        std::cout << "add1" << std::endl;
        return a + b;
    }
    
    double add(double a, double b) {
        std::cout << "add1" << std::endl;
        return a + b;
    }
    
    int main() {
        std::cout << add(3, 3) << std::endl;
        std::cout << add(3.14, 3.14) << std::endl;
    }
    
    参数数量不同的重载
    # include "iostream"
    int add(int a, int b) {
        std::cout << "add1" << std::endl;
        return a + b;
    }
    
    int add(int a, int b, int c) {
        std::cout << "add2" << std::endl;
        return a + b + c;
    }
    
    int main() {
        std::cout << add(3, 3) << std::endl;
        std::cout << add(3, 3, 4) << std::endl;
    }
    
    参数顺序不同的重载
    # include "iostream"
    
    int add(int a, double b) {
        std::cout << "add1" << std::endl;
        return a + int(b);
    }
    
    int add(double a, int b) {
        std::cout << "add2" << std::endl;
        return int(a) + b;
    }
    
    
    int main() {
        std::cout << add(3, 3.14) << std::endl;
        std::cout << add(3.15, 3) << std::endl;
    }
    

    这个函数的输出是这样的

    add1
    6
    add2
    6
    

    但是,但是,但是如果我们注释掉一个add函数,她的输出就是这样的

    add1
    6
    add1
    6
    

    所以说明了什么,说明了编译器很智能,是的,很智能,参数只是顺序不同的话,有那个确定顺序的重载会去找那个确定顺序的重载,没有的话也可以找到一个参数类型相同的。

    引用与函数重载

    我们发现下面这个函数是无法被编译的

    # include "iostream"
    
    int add(int a, int b) {
        std::cout << "add1" << std::endl;
        return a + int(b);
    }
    
    int add(int &a, int &b) {
        std::cout << "add2" << std::endl;
        return a + b;
    }
    
    int main() {
        int a = 1;
        std::cout << add(a, a) << std::endl;
    }
    

    一个函数add的参数是两个整型,另一个函数的参数是两个整型的引用,但是会报错

    error: call of overloaded 'add(int&, int&)' is ambiguous
    

    说这个调用时模糊的,模棱两可的,为什么呢,主要的原因是因为在编译器看来,一个整数的引用和一个整数是等价的,所以编译器并不知道这里要调用哪个函数,所以类型引用和类型是一个特征标

    const与函数重载

    和上面的引用一样,下面的程序也无法被编译

    # include "iostream"
    
    int add(int a, int b) {
        std::cout << "add1" << std::endl;
        return a + int(b);
    }
    
    int add(const int a, const int b) {
        std::cout << "add2" << std::endl;
        return a + b;
    }
    
    int main() {
        int a = 1;
        std::cout << add(a, a) << std::endl;
    }
    

    因为两个add函数被视为一个,相当于函数被重新定义了,这是cpp不允许的,但是const指针和普通的指针的特征标不一样,

    # include "iostream"
    
    int add(int* a, int* b) {
        std::cout << "add1" << std::endl;
        return *a + *b;
    }
    
    int add(const int* a, const int* b) {
        std::cout << "add2" << std::endl;
        return *a + *b;
    }
    
    int main() {
        int a = 1;
        std::cout << add(&a, &a) << std::endl;
    }
    

    上面这段程序可以被正常执行就是因为普通的指针可以赋值给普通指针也可以被赋值为const指针,但是const指针只能被赋值给const指针,这么说可能有点绕,那上面的程序做个例子,上面的程序其实是可以执行add1和add2的,都是合法的,但是如果我们传入的是一个const指针的话,只能执行add2了

    何时使用重载

    重载函数很好用,但是不应该被滥用,只有当函数执行相同的任务但是参数不同时才应该被使用。而且不仅重载,使用默认参数也可以达到一定的重载功能。

    名称修饰

    C++如何跟踪一个重载参数呢,他给了这些函数不同的函数名,也就是编译器执行的名称修饰或者叫名称矫正,他根据每个函数中的形参列表对函数名进行加密处理,比如下面这个未处理的函数原型

    long MyFunctionFoo(int,float);
    

    这种格式对于人很友好但是对于编译器并不友好,所以会被修饰

    ?MyFunctionFoo@@YAXH
    

    对原始名称进行的表面看来无意义的修饰(或矫正,因人而异)将对参数数目和类型进行编码;添加的一组符号随函数特征标而异,而修饰时使用的约定随编译器而异。

    名称修饰后的函数名其实已经对不同函数重载已经有了不同的函数名。

  • 相关阅读:
    Ubuntu文件操作(压缩与解压缩、用户组管理、权限)
    物联网:用python调入机器学习分析物联网数据入侵检测模块
    RabbitMQ基础概念-02
    随机手机号查询易语言代码
    【JS重点15】原型对象概述
    【重拾C语言】四、循环程序设计(后判断条件循环、先判断条件循环、多重循环;典例:计算平均成绩、打印素数、百钱百鸡问题)
    人工智能行业源代码防数据防泄密需求分析
    服务器搭建日记(一):准备工作
    不清楚的照片如何变清晰?教你几招变清晰的方法
    【云原生之k8s】KubeSphere介绍及安装
  • 原文地址:https://blog.csdn.net/weixin_43903639/article/details/126961438