• 重载函数与函数模板(转)


    原文地址:http://www.jizhuomi.com/software/45.html

          hello,everyone,鸡啄米上一节讲到的是函数的参数传递和内联函数,这一讲鸡啄米会给大家讲点稍微有点难度的函数重载和函数模板,如果大家把之前的编程入门课程都掌握了,这一讲的内容自己上机试下就很容易理解了。

          一.重载函数

          现实生活中的一个词可能有多种含义,比如,洗衣服、洗头、洗车,都有一个洗字,但是他们的操作方式是不一样的。函数也一样,有时候它们的操作不完全一样但是名字一样,这就是重载函数。

          重载函数就是,两个以上的函数取相同的函数名,但是函数形参的个数或者类型不同,编译器会根据实参与形参的类型和个数进行最佳匹配,自动确定调用哪一个函数。

          为什么要有重载函数呢?因为如果没有重载函数,那么对不同类型的数据进行类似的操作也要定义不同名称的函数,比如加法函数,就必须对整数加法和浮点数加法分别定义不同的函数名:

    int nadd(int a, int b);
    float fadd(float a, float b);

          这样调用需要记住的函数名太多,而且功能类似,很不方便。鸡啄米给大家举几个重载函数的例子:形参类型不同的例子:

    int   add(int x,int y);
    float add(float x,float y);

          形参个数不同的例子:

    int add(int x,int y);
    int add(int x,int y,int z);

          1.重载函数的形参不管是类型还是个数必须有一样是不同的。因为编译器就是看实参和哪个函数的形参的类型及个数匹配,来判断调用哪个函数,如果函数名、 形参类型和个数相同,即使函数返回值类型不同,编译器也会认为是函数重复定义的语法错误,就是说它认为是一个函数。以下两种是错误的重载函数:

      int add(int x,int y);
      int add(int a,int b);

          上面两个函数虽然形参名不同,但是编译器不会以形参名来区分函数,它会认为这是一个函数。我们以后也要记住,若只改变形参名则函数不会变,调用的地方也不必变。

    int add(int x,int y);
    void add(int x,int y);

          上面这两个函数返回值不同,确实是两个函数,但是编译器也不会以返回值来区分函数,也会认为是重复定义。

          2.重载函数都是进行类似的操作,不要把不同的功能定义成重载函数,否则会让人对调用有误解,比如:

     int add(int x,int y)
    {  
          return x+y;
    }
    
    float add(float x,float y)
    {  
           return x-y; 
     }

          这两个函数一个是实现的两个数的加法,一个是实现减法,在语法上并没有问题。但是功能不一样但是都叫add,我们调用的时候是不是会混淆?       鸡啄米给大家一个重载函数的例子,大家仔细研究下代码,上机试下,通过上面的讲解,很容易理解:

    #include<iostream>
    using namespace std;
    int add(int m,int n);       // 函数调用前必须先声明函数原型
    float add(float x,float y);
         
    int main()
    {
        int m, n;
        float x, y;
        cout<<"Enter two integer: ";
        cin>>m>>n;
        cout<<"integer <<m<<'+'<<n<<"="<<add(m,n)<<endl;
        cout<<"Enter two float: ";
        cin>>x>>y;
        cout<<"float "<<x<<'+'<<y<<"= "<<add(x,y)<<endl;
        return 0;
    }
    int add(int m,int n)
    { 
        return m+n;
    }
    float add(float x,float y)
    { 
        return x+y; 
    }

          屏幕先输出Enter two integer:,我们输入2 3,则屏幕会接着显示integer 2+3=5,然后继续提示Enter two float:,我们继续输入2.1 3.4,最后屏幕会出现float 2.1+3.4=5.5。

    二.函数模板

            有时候我们使用重载函数还不能达到最优的效果,比如,两个求绝对值的函数:

     int abs(int x)
    {
          return x<0 ? -x:x;
    }
    double abs(double x)
    {
          return x<0 ? -x:x;
    }

          大家观察下这两个函数,这两个函数只是返回值类型和参数类型不同,功能完全一样,如果能有办法写一段通用的代码适用于多种不同的数据类型,就是不用 像上面那样写两个函数而只是一段代码就能实现两个函数的功能,那代码的复用性不是更高了吗?开发效率也会提高的。这就要函数模板来实现了。

          模板是有可以使用和操作任何数据类型的通用代码构成,这种程序设计叫做参数化程序设计,因为它把数据类型当成了参数,可以用来创建一个通用功能的函数,支持多种不同类型的形参和返回值。函数模板的定义形式是:

    template <typename 标识符>
             函数定义

           鸡啄米给大家一个上面那样求绝对值的函数模板示例:

    #include<iostream>
    using namespace std;
    
    template <typename T>
    T abs(T x)
    {
          return x<0 ? -x:x;
    }
         
    
    int main()
    {
           int     n = 5;
           double  d = -2.3;
           cout << abs(n) << endl;
           cout << abs(d) << endl;
           return 0;
    }

          鸡啄米给大家分析下这个程序,编译器会根据调用abs函数时传入实参的类型来确定函数模板的类型参数是什么类型。上面使用调用表达式abs(n)时,因为n是int类型,所以模板中类型参数T就是int,然后编译器会以函数模板为样板生成一个函数:

     int abs(int x)
    {
          return x<0 ? -x:x;
    }

          同样,对于调用表达式abs(d),因为d是double类型,所以类型参数T就是double,编译器会根据函数模板生成下面的函数:

    double abs(double x)
    {
          return x<0 ? -x:x;
    }

          所以,abs(n)实际上调用的是函数模板生成的函数:int abs(int x)。而abs(d)调用的是由函数模板生成的函数:double abs(double x)。

           最后,鸡啄米跟大家简单说下C++系统函数。C++系统库中提供了几百个函数供我们使用,我们只要用include指令包含相应的头文件就可以使用了。比 如,包含了math.h文件我们就可以使用abs、sqrt、sin等函数。如果需要用到一些库函数可以msdn上查也可以上网查。

  • 相关阅读:
    基于阿里云GPU云服务器的AIACC助力UC搜索业务性能提效380%,每年节省数千万成本
    如何在 ACK 中使用 MSE Ingress
    面向对象分析与设计的底层逻辑
    当 AI 邂逅绘画艺术,能迸发出怎样的火花?
    是什么让一段20行代码的性能提升了10倍
    我,PolarDB云原生数据库,5年来实现这些重磅技术创新
    一图看懂天河文链如何实现云原生架构升级
    首次全面解析云原生成熟度模型:解决企业「诊断难、规划难、选型难」问题
    C++快速初始化vector
    Grid布局指定列数时,行高自适应为元素高度
  • 原文地址:https://www.cnblogs.com/fuxianfeng1988/p/3273141.html
Copyright © 2020-2023  润新知