• C++学习笔记——(四)重载、函数模板


    1、函数重载

    • 原理
      • 允许多个函数共享同一个函数名
      • 针对不同类型参数,提供不同操作
    • 案例:加法操作符“+”重载
    • 原因
      • 对不同类型数据,执行相同的一般性操作(大量重复使用)
    • 方法
      • 如果两个函数的参数表中参数的个数或类型不同,则认为这两个函数是重载的
        • void print( const string & );
        • void print( vector<int> & );
      • 如果两个函数的返回类型和参数表精确匹配,则第二个声明被视为第一个的重复声明
        • void print( const string &str );
        • void print( cons t string & );     // 重复声明
      •  如果两个函数的参数表相同,但是返回类型不同,则第二个声明被视为第一个的错误重复声明,会被标记为编译错误
        • unsigned int max( int i1, int i2 );
        • int max( int , int );   // 错误: 只有返回类型不同
        • 函数的返回类型不足以区分两个重载函数
      •  如果在两个函数的参数表中,只有缺省实参不同,则第二个声明被视为第一个的重复声明
        • int max( int *ia, int sz );
        • int max( int *, int = 10 );   // 重复声明
      •  如果两个函数参数表的区别,只在于一个使用了 typedef。而另一个使用了与 typedef相应的类型,则该参数表视为相同
        • typedef double DOLLAR;  // typedef 并不引入一个新类型
        •  extern DOLLAR calc( DOLLAR );
        • extern int calc( double );   // 错误: 相同参数表,不同返回类型
      •  当一个参数类型是 const 或 volatile 时,在识别函数声明是否相同时,并不考虑 const 和 volatile 修饰符
        • void f( int );
        • void f( const int );  // 重复声明
        • PS:
          • 参数是 const,这只跟函数的定义有关系,它意味着函数体内的表达式不能改变参数的值
          • 但是,对于按值传递的参数,这对函数的用户是完全透明的
          • 用户不会看到函数对按值传递的实参的改变
          • 当实参被按值传递时,将参数声明为 const 不会改变可以被传递给该函数的实参种类
          • 任何 int 型的实参都可以被用来调用函数 f(const int),因为两个函数接受相同的实参集
          • 所以上述两个声明并没有声明一个重载函数
          • 但是,如果把 const 或 volatile 应用在指针或引用参数指向的类型上,则在判断函数声明是否相同时,就要考虑 const 和 volatile 修饰符
    • 重载函数匹配
      • 精确匹配
        • 包括参数的强制类型转换
      • 类型转换匹配(系统默认的数据类型转换)
      • 不匹配
    • 什么时候不使用重载
      • 不同函数名可使程序更易于理解
      • 参数表完全相同的两个函数
    • PS:重载函数应在同一个域内声明,使用using可使不同域的函数在同一个域发生重载

     

    2、函数模板

    • 原理
      • 函数模板提供了一种机制,通过它我们可以保留函数定义和函数调用的语义
      • 在一个程序位置上封装了一段代码,确保在函数调用之前实参只被计算一次
      • 而无需像宏方案那样绕过 C++的强类型检查
    • 概述
      •  函数模板提供一个种用来自动生成各种类型函数实例的算法
      • 程序员对于函数接口(参数和返回类型)中的全部或者部分类型进行参数化(parameterize),而函数体保持不变
    • 例子
      • 用一个函数的实现在一组实例上保持不变,并且每个实例都处理一种惟一的数据类型,
      • 如函数 min(),该函数就是模板的最佳候选者,下面是 min()的函数模板定义

            template <class MyClass>

            MyClass min( MyClas a, MyClass b ){ 

              return a < b ? a : b;

            }

            int main() {

              min( 10, 20 );         // ok: int min( int, int );

              min( 10.0, 20.0 );   // ok: double min( double, double );

              return 0;

            }

    • 在程序的运行过程中 MyClass 会被各种内置类型和用户定义的类型所代替
    • 使用方法
      • 关键字 template 总是放在模板的定义与声明的最前面
      • 关键字后面是用逗号分隔的模板参数表(template parameter list), 它用尖括号括起来
      • 该列表是模板参数表,不能为空
      • 模板参数可以是一个模板类型参数(template type parameter),它代表了一种类型
      • 模板参数也可以是一个模板非类型参数(template nontype parameter),它代表了一个常量表达式
    • 特点
      • 当一个名字被声明为模板参数之后它就可以被使用了,一直到模板声明或定义结束为止
      • 如果在全局域中声明了与模板参数同名的对象函数或类型,则该全局名将被隐藏
      • 在函数模板定义中声明的对象或类型不能与模板参数同名
      • 如果一个函数模板有一个以上的模板类型参数,则每个模板类型参数前面都必须有关键字 class 或 typename
      • 函数模板是对一组函数的规则描述,其本身不能定义任何函数,当对模板使用特定类型进行实例化时,才会生成一个实体函数
    • 重载函数模板
      • template <typename Type>

            Type min( const Array<Type>&, int );    // #1

      • template <typename Type>

            Type min( const Type*, int );                  // #2

      • template <typename Type>

            Type min( Type, Type );                         // #3

  • 相关阅读:
    浏览器回退
    几个小东西
    获取用户的IP
    easyui datagrid中 formatter的用法
    vscode安装go语言插件失败解决方法
    c#项目NLOG不显示日志
    C# 抽象类与接口的区别
    用SQL Server事件探查器创建跟踪
    使用MathJax在博客园里添加数学公式
    概率主题模型简介 Introduction to Probabilistic Topic Models
  • 原文地址:https://www.cnblogs.com/snailt/p/13600494.html
Copyright © 2020-2023  润新知