C++函数重载的深入解析

我们在开瓶瓶罐罐的时候,经常会遭遇因各种瓶口规格不同而找不到合适的工具的尴尬。所以有时候就为了开个瓶,家里要备多种规格的开瓶器。同样是开个瓶子嘛,何必这么麻烦?于是有人发明了多功能开瓶器,不管啤酒瓶汽水瓶还是软木塞的红酒瓶都能轻松打开。

然而开瓶器的问题也会发生到程序设计中。比如我们要编写一个函数来求一个数的绝对值,然而整数、浮点型数、双精度型数都有绝对值,但为它们编写的函数返回值类型却是各不相同的。比如:


代码如下:

int iabs(int a);
float fabs(float a);
double dabs(double a);

这样是不是有点备了多种开瓶器的感觉?我们能不能在程序设计中也做一个多功能的开瓶器,把所有数据类型的求绝对值都交给abs这一个函数呢?

在C++中,我们也能够把具有相同功能的函数整合到一个函数上,而不必去写好多个函数名不同的函数,这叫做函数的重(音chóng)载(Overload)。重载的本质是多个函数共用同一个函数名。

我们先来看一个函数重载的实例:(程序6.3)


代码如下:

#include "iostream.h"
int abs(int a);//当参数为整型数据时的函数原型
float abs(float a);//当参数为浮点型数据时的函数原型
double abs(double a);//当参数为双精度型数据时的函数原型
int main()
{
   int a=-5,b=3;
   float c=-2.4f,d=8.4f;
   double e=-3e-9,f=3e6;
   cout <<"a=" <<abs(a) <<endl <<"b=" <<abs(b) <<endl;//输出函数返回的结果
   cout <<"c=" <<abs(c) <<endl <<"d=" <<abs(d) <<endl;
   cout <<"e=" <<abs(e) <<endl <<"f=" <<abs(f) <<endl;
   return 0;
}
int abs(int a)//函数定义
{
   cout <<"int abs" <<endl;//显示运行了哪个函数
   return (a>=0?a:-a);//如果a大于等于零则返回a,否则返回-a。
}
float abs(float a)
{
   cout <<"float abs" <<endl;
   return (a>=0?a:-a);
}
double abs(double a)
{
   cout <<"double abs" <<endl;
   return (a>=0?a:-a);
}
运行结果:
int abs
int abs
a=5
b=3
float abs
float abs
c=2.4
d=8.4
double abs
double abs
e=3e-009
f=3e+006

运行结果表明,abs函数果然能够处理三种不同数据类型的数据了。那么我们怎样才能自己造一个“多功能工具”呢?

其实要编写一个重载函数并不是很麻烦。首先,我们要告诉电脑,同一个函数名存在了多种定义,所以,我们要给同一个函数名写上多种函数原型(如程序6.3的第二到第四行);其次,我们要对应这些函数原型,分别写上这些函数的定义(如程序6.3的主函数体之后,对三个abs函数的定义)。

然而电脑又是如何来识别这些使用在不同环境下的“工具”的呢?
在日常生活中使用到多功能工具,如果我们不知道具体应该使用哪个工具,我们会把每个工具放上去试一试,如果只有唯一一个工具适合,那么我们就毫无疑问地能够确定就是使用它了。但是如果出现了两个或者两个以上工具都能适合,我们就分不清到底应该使用哪个是正确的了。

电脑的做法和我们是类似的。电脑是依靠函数声明时参数表中参数个数、各参数的数据类型和顺序来判断到底要运行哪个函数的。因此,当重载函数参数表完全相同的时候,电脑便无法判断应该运行哪个函数,于是程序就出错了。

我们了解了电脑是如何识别重载函数以后,发现要编写一个重载函数还是需要注意一些地方的,那就是:在重载函数中,任意两个函数的参数表中的参数个数、各参数的数据类型和顺序不能完全一样。例如int func(int a,char b)和float func(int c,char d)就不能重载,因为它们的参数个数、各参数的类型和顺序完全一样,即使形参名不同、返回值类型不同也是无济于事的。

在调用一个重载函数时,可能会发生找不到一个完全合适的函数。这时候,就需要进行数据类型的转换。由于这种方法可能导致数据丢失或数据类型不严格符合,且在充分考虑问题后,这种情况是可以尽量避免的,所以这里不再就这个问题展开论述。有兴趣的读者可以查阅其他C++的参考资料。

算法时间:重载函数
从某种意义上说,重载函数是方便了函数的使用者。在前一节我们知道,如果完成了所有函数的编写,那么完成一个程序就像搭积木一样简单了。然而如果功能相似名字却不同的函数太多,那么多“积木”搭起来也未必简单。当函数的编写者充分考虑了不同情况下应该运行稍有不同的函数,函数的使用者就不必为这些小细节而烦恼了。不过重载函数的函数名还是应该符合其功能,如果把功能完全不同的函数重载,那么就大大影响了程序的可读性。

(0)

相关推荐

  • 详解C++中的内联函数和函数重载

    内联函数(内嵌函数,内置函数) 调用函数时需要一定的时间和空间的开销.C++提供一种提高效率的方法,即在编译时将函数调用处用函数体替换,类似于C语言中的宏展开.这种在函数调用处直接嵌入函数体的函数称为内联函数(inline function),又称内嵌函数或内嵌函数. 指定内联函数的方法很简单,只需要在定义函数时增加 inline 关键字. 注意:是在函数定义时增加 inline 关键字,而不是在函数声明时.在函数声明时增加 inline 关键虽然没有错误,但是也没有任何效果 inline 关键

  • C++中函数重载实例详解

    C++中函数重载实例详解 函数重载: 1.具有相同的名称,执行基本相同的操作,但是使用不同的参数列表. 2.函数具有多态性. 3.编译器通过调用时参数的个数和类型确定调用重载函数的哪个定义. 4.只有对不同的数据集完成基本相同任务的函数才应重载. 函数重载的优 点 1.不必使用不同的函数名 2.有助于理解和调试代码 3.易于维护代码 接下来直接上代码: #include <iostream> using namespace std ; void say_hello(void) { cout &

  • 深度探究C++中的函数重载的用法

    C++ 允许同一范围内具有相同名称的多个函数的规范.这些函数称为重载函数,"重载"中对其进行了详细介绍.利用重载函数,程序员可以根据参数的类型和数量为函数提供不同的语义. 例如,采用字符串(或 char *)参数的 print 函数执行的任务与采用"双精度"类型的参数的函数执行的任务截然不同.重载允许通用命名并使程序员无需创建名称,例如 print_sz 或 print_d.下表显示了 C++ 使用函数声明的哪些部分来区分同一范围内具有相同名称的函数组. 重载注意事

  • C++函数重载详解及实例代码

    C++函数的重载 定义 在同一个作用域中,函数名相同,函数的参数列表不同的函数之间构成重载关系,在不同作用域中的同名函数遵循标识符隐藏的原则 ATTENTION:重载与函数的返回值类型无关,因为声明一个函数不需要返回类型,所以无法用来区分哪个函数 常函数和普通成员函数之间构成重载,重载时常对象调用常成员函数,一般对象调用一般成员函数 class A{ - public: void getVal()const{-} void getVal(){-} }; int main(){ const A a

  • C++中构造函数重载

    #include<stdio.h> class Test { private: int i; int j; int k; public: Test() { i=j=k=0; } Test(int v) { i=j=k=v; } void print() { printf("i= %d, j=%d, k=%d \n",i,j,k); } }; int main() { Test t1(1); Test t2=2; Test t3=Test(3); t1.print(); t2

  • C++函数重载的深入解析

    我们在开瓶瓶罐罐的时候,经常会遭遇因各种瓶口规格不同而找不到合适的工具的尴尬.所以有时候就为了开个瓶,家里要备多种规格的开瓶器.同样是开个瓶子嘛,何必这么麻烦?于是有人发明了多功能开瓶器,不管啤酒瓶汽水瓶还是软木塞的红酒瓶都能轻松打开. 然而开瓶器的问题也会发生到程序设计中.比如我们要编写一个函数来求一个数的绝对值,然而整数.浮点型数.双精度型数都有绝对值,但为它们编写的函数返回值类型却是各不相同的.比如: 复制代码 代码如下: int iabs(int a);float fabs(float

  • 深入了解C++函数重载解析策略

    参考<C++ Primer Plus>(第6版)中文版,Stephen Prata 著,张海龙 袁国忠译,人民邮电出版社.C++ 使用重载解析策略来决定为函数调用使用哪一个函数定义.重载解析过程大致分为如下三步: 第 1 步:创建候选函数列表,只要求函数名一样即可,对函数特征标以及是否为模板函数无要求: 第 2 步:在上一步的基础上创建可行函数列表,包含特征标完全匹配的常规函数或模板函数.以及实参隐式转换后完全匹配的常规函数或模板函数,这些都是参数数目正确的函数: 第 3 步:在上一步的基础上

  • jQuery基于函数重载实现自定义Alert函数样式的方法

    本文实例讲述了jQuery基于函数重载实现自定义Alert函数样式的方法.分享给大家供大家参考,具体如下: (function(){ window.alert = function(text) { text=text.toString().replace(/\\/g,'\\').replace(/\n/g,'<br />').replace(/\r/g,'<br />'); //解析alert内容中的换行符 var alertdiv='<div id="alertd

  • python如何重载模块实例解析

    本文首先介绍了Python中的模块的概念,谈到了一个模块往往由多个模块组成,然后通过具体实例,分析了模块重载的相关内容,具体介绍如下. 模块是Python程序架构的一个核心概念,较大的程序往往以多个模块文件的形式呈现,一个模块被设计成主文件或顶层文件,用来启动整个Python程序.每个以.py为后缀的Python源代码文件都是一个模块,其他文件可通过"导入"读取这个模块的内容.从一般意义上讲,模块就是变量名的封装.如写一个模块test.py,包含一个两个变量名name.age. nam

  • 关于Mybatis的mapper接口函数重载问题

    目录 Mybatis的接口函数能不能进行重载? 语法层面 Mybatis框架方面 测试 MyBatis实现方法重载的小技巧 QuestionMapper.java QuestionMapper.xml Mybatis的接口函数能不能进行重载? mybatis版本:3.4x java版本:java 8 语法层面 1.接口的方法可以进行重载,因为 java 语法可以让接口函数进行重载. Mybatis框架方面 1.结论:可以有条件的进行重载. 2.为什么会有这个问题?:mybatis里面将接口里面的

  • C++深入浅出讲解函数重载

    目录 前言 函数重载 1.1 函数重载的概念 1.2 函数重载的意义 1.3 名字修饰(name Mangling) 1.4 extern "C" 前言 自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重载了. 比如:以前有一个笑话,国有两个体育项目大家根本不用看,也不用担心.一个是乒乓球,一个是男足.前者是“谁也赢不了!”,后者是“谁也赢不了!” 函数重载 1.1 函数重载的概念 函数重载: 它是函数的一种特殊情况,C++允许在同一作用域中同一作用域

  • C++深入讲解函数重载

    目录 函数重载 概念 重载依据 值型别 判断函数重载的规则 名字粉碎-名字修饰 函数重载 概念 在C++中可以为两个或者两个以上函数提供相同的函数名称,只要参数类型不同,或者参数数目不同,参数顺序不同,即参数表不同,那么就认为是函数的重载.(函数名+参数表) // my_max + 参数表 int my_max(int a,int b) { return a > b ? a : b; } char my_max(char a,char b) { return a > b ? a : b; }

  • 通过实例理解javascript中没有函数重载的概念

    将函数名想象为指针,也有助于理解为什么ECMAScript中没有函数重载的概念.如下例子: 复制代码 代码如下: function addSomeNum(num) {     return num+100; } function addSomeNum(num) {     return num+200; } var result=addSomeNum(100);//300 显然,这个例子中声明了两个同名函数,而结果则是后面的函数覆盖了前面的函数.以上代码实际上与下面的代码是一致的. 复制代码 代

  • C++中const用于函数重载的示例代码

    常成员函数和非常成员函数之间的重载 首先先回忆一下常成员函数 声明:<类型标志符>函数名(参数表)const: 说明: (1)const是函数类型的一部分,在实现部分也要带该关键字. (2)const关键字可以用于对重载函数的区分. (3)常成员函数不能更新类的成员变量,也不能调用该类中没有用const修饰的成员函数,只能调用常成员函数. (4)非常量对象也可以调用常成员函数,但是如果有重载的非常成员函数则会调用非常成员函数. 重载看例子: #include<iostream> u

  • MYSQL updatexml()函数报错注入解析

    首先了解下updatexml()函数 UPDATEXML (XML_document, XPath_string, new_value); 第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc 第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程. 第三个参数:new_value,String格式,替换查找到的符合条件的数据 作用:改变文档中符合条件的节点的值 改变XML_document中符合X

随机推荐