C++重载的奥义之函数重载详解

 更新时间:2023年04月18日 10:40:07   作者:Sharemaker  
函数重载是C++多态(静态多态)的特征体现,它可以允许重复使用同一个函数名(篮子)的函数,但是函数的参数列表(篮子装的东西)是可以不一样的。下面就简单讲讲C++中函数重载的相关应用吧

一、基本定义        

重载,顾名思义从字面上理解就是重复装载,打一个不恰当的比方,你可以用一个篮子装蔬菜,也可以装水果或者其它,使用的是同一个篮子,但是可以用篮子重复装载的东西不一样。

函数重载是C++多态(静态多态)的特征体现,它可以允许重复使用同一个函数名(篮子)的函数,但是函数的参数列表(篮子装的东西)是可以不一样的。这样就可以利用函数的重载功能设计一系列功能相近,但是功能细节不一样的函数接口。

二、应用举例        

以同一个函数printData为例:

#include <iostream>
using namespace std;

void printData(const char *str, int num)
{
  //函数体;
}

void printData(const char *str)
{
  //函数体;
}

void printData(double data, int num)
{
  //函数体;
}

void printData(int data, int num)
{
  //函数体;
}

void printData(long data, char num)
{
  //函数体;
}

class Test
{
  public:
         void MyPrint(int num) {cout << "class int: " << num << endl;}
         void MyPrint(float num) {cout << "class float: " << num << endl;}
         void MyPrint(char num) {cout << "class char: " << num << endl;}
};

int main(void)
{
  printData("hello", 5); // (const char *str, int num)
  printData("hello"); // (const char *str)
  printData(1993.0, 97);
  printData(1993, 98);
  printData(1993L, 99);
  Test test1;
  test1.MyPrint(2); // class int: 2
  test1.MyPrint(2.0f); // class float: 2.0 浮点型必须要显式类型,否则编译器不知道该转换为int还是float。
  test1.MyPrint("hello"); // class char: hello
  return 0;
}

使用重载函数时,需要在函数调用中使用与对应的重载函数匹配的函数参数类型。

而如下:

unsigned int para = 4321;
printData(4321, 5);

此时的printData调用和哪个原型匹配呢?答案它不与任何函数原型匹配,而没有匹配的原型不会停止调用其中某一个函数,C++会尝试用标准的强制类型转换与之匹配,比如使用 printData(double data, int num),就可以将para的类型强制转换为double类型。但是还有printData(int data, int num)和printData(long data, char num)这两个函数可以强制转换para。因此,C++将拒绝这种函数的调用,将这种调用视为错误。

重载函数通常用在同一个作用域内,用同一个函数名命名一组功能相似的函数,这样做减少了函数名的数量,提高了函数的通用性,避免了名字空间的污染,对于程序的可读性有很大的好处。

三、非函数重载的情况

下面这种两种情况不能视为函数重载:

 int fun(int a);
 int fun(int &a);

从编译器的角度出发,参数a与参数列表原型int a和int &a都匹配,编译器无法确定使用哪个函数,为避免这种混乱,编译器在检查参数类型时将把类型本身和类型引用看作是同一个特征类型。

int fun(int a, float b);
double fun(int a, float b);

C++不允许这样的方式重载函数,虽然返回值可以不一样,但是参数列表必须不一样。

四、函数重载的使用原则

(1)、仅当函数的基本功能比较相近,但是需要使用不同形式的参数实现功能时才应该使用函数重载,尽量不要用同一函数名去实现完全不相干的功能;

(2)、在同一个作用范围内使用函数重载,同一个范围即:同一个命名空间或者同一个类等;

(3)、重载函数的名称必须相同,函数的参数列表须不相同,即参数列表中参数的类型,参数的个数或参数的顺序不相同;

(4)、重载函数可以有相同的返回值类型或者不同的返回值类型,反之仅仅是返回类型不同不足以作为函数的重载。

五、FAQ

1、C++中对函数重载是如何处理的?

在.cpp文件中,虽然两个函数的函数名一样,但是,C++编译器在内部使用“名称修饰”或“名称矫正”转换,它根据函数中参数列表的区别为每个函数进行加密 ,例如:

int fun(int a, float b)和double fun(int a, float b)

编译器在内部可以转换为:

?fun@@YAHHH@Z和?fun@@YAMMM@Z

"?"表示名称开始,"?"后边是函数名;“@@YA”表示参数表开始,后边的3个字符分别表示返回值类型,两个参数类型;“@Z”表示名称结束。

由于在.cpp文件中,两个函数生成的符号表中字符的名称不一样,所以是可以编译通过的。

2、C语言中为什么不能支持函数重载?

编译器在编译.c文件时,只会给函数进行简单的重命名。具体的方法是给函数名之前加上"_”;所以编译前两个函数名相同的函数在编译之后的函数名也照样相同;因此调用时会因为不知道到底调用哪个而出错。

int fun(int a, float b)和double fun(int a, float b)

编译器在内部都转换为:_fun,无法区分,

只有不同的函数名字int fun1(int a, float b)和double fun2(int a, float b)

编译器在内部转换为:_fun1和_fun2,这才能区分开来。

以上就是C++重载的奥义之函数重载详解的详细内容,更多关于C++函数重载的资料请关注脚本之家其它相关文章!

相关文章

  • 浅析VSCode launch.json中的各种替换变量的意思 ${workspaceFolder} ${file} ${fileBasename} ${fileDirname}等

    浅析VSCode launch.json中的各种替换变量的意思 ${workspaceFolder} ${file} $

    这篇文章主要介绍了VSCode launch.json中的各种替换变量的意思 ${workspaceFolder} ${file} ${fileBasename} ${fileDirname}等,非常不错具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • C语言数据结构之判断循环链表空与满

    C语言数据结构之判断循环链表空与满

    这篇文章主要介绍了C语言数据结构之判断循环链表空与满的相关资料,希望通过本文能帮助到大家,让大家掌握这部分内容,需要的朋友可以参考下
    2017-10-10
  • 解析VC中创建DLL,导出全局变量,函数和类的深入分析

    解析VC中创建DLL,导出全局变量,函数和类的深入分析

    本篇文章是对VC中创建DLL,导出全局变量,函数和类进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++中对象的赋值与复制操作详细解析

    C++中对象的赋值与复制操作详细解析

    对象之间的赋值也是通过赋值运算符“=”进行的。本来赋值运算符“=”只能用来对单个的变量赋值,现在被扩展为两个同类对象之间的赋值,这是通过对赋值运算符的重载实现的
    2013-10-10
  • C/C++ProtoBuf使用小结

    C/C++ProtoBuf使用小结

    ProtoBuf全称:protocol buffers,直译过来是:“协议缓冲区”,是一种与语言无关、与平台无关的可扩展机制,用于序列化结构化数据,这篇文章主要介绍了C/C++ProtoBuf使用,需要的朋友可以参考下
    2024-01-01
  • C++ 花括号{}初始化小结

    C++ 花括号{}初始化小结

    在C++11及以后的版本中,花括号{}语法在不同语境下有不同的用法,本文就详细的介绍C++ 花括号{}初始化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • c++ 面向对象设计五大原则

    c++ 面向对象设计五大原则

    这篇文章主要介绍了c++ 面向对象设计五大原则,帮助大家更好的理解和学习c++面向对象设计,感兴趣的朋友可以了解下
    2020-08-08
  • 最新C语言中getchar的使用

    最新C语言中getchar的使用

    getchar()是在输入缓冲区顺序读入一个字符(包括空格、回车和Tab) ,getchar()是stdio.h中的库函数,它的作用是从stdin流中读入一个字符,本文给大家介绍getchar的使用,感兴趣的朋友跟随小编一起看看吧
    2022-12-12
  • 用C语言实现简单五子棋小游戏

    用C语言实现简单五子棋小游戏

    这篇文章主要为大家详细介绍了用C语言实现简单五子棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • C++中move的使用及说明

    C++中move的使用及说明

    这篇文章主要介绍了C++中move的使用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08

最新评论