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;
}
double my_max(double a,double b)
{
return a > b ? a : b;
}
//每个同名函数的参数表是惟一,
int main()
{
int ix = my_max(12,23);
double dx = my_max(12.23,34.45);
char chx = my_max('a','b');
return 0;
}

重载依据

  • 可以用值型别和形参类型作为重载依据
  • 函数的返回类型不同不能作为函数重载的依据
  • 在定义重载函数时,不能轻易给出函数参数的默认值,容易在调用时候产生二义性

值型别

函数的左值:和数据类型无关,有名字并且可以取地址

函数的有值:字面常量,不能取地址的

右值引用: && ,可以引用字面常量,引用右值

int && r = 10;
//可以引用字面常量

判断函数重载的规则

1.如果两个函数的参数表相同, 但是返回类型不同,会被标记为编译错误:函数的重复声明。

int my_max(int a,int b)
{
return a > b ? a : b;
}
unsigned int my_max(int a,int b) // error;
{
return a > b ? a : b;
}
int main()
{
int ix = my_max(12,23);
unsigned int = my_max(12,23); // error;
reutrn 0;
}

2.参数表的比较过程与形参名无关。

// 声明同一个函数
int my_add(int a,int b);
int my_add(int x,int y);

3.如果在两个函数的参数表中,只有缺省实参不同,则第二个声明被视为第一个的重复声明

void Print(int *br,int n);
void Print(int *br,int len = 10);

4.typedef 名为现有的数据类型提供了一个替换名,它并没有创建一个新类型 ,因此 ,如果两个函数参数表的区别只在于一个使用了 typedef ,而另一个使用了与 typedef 相应的类型。则该参数表被视为相同的参数列表。

typedef unsigned int u_int;
int Print(u_int a)
int Print(unsigned int b);

5.当一个形参类型有 const 或 volatile 修饰时,如果形参是按值传递方式定义,在识别函数声明是否相同时,并不考虑 const 和 volatile 修饰符.

void fun(int a){ }
void fun(const int a) { }

6.当一个形参类型有 const 或 volatile 修饰时,如果形参定义指针或引用时,在识别函数声明是否相同时 ,就要考虑 const 和 volatile 修饰符.

void fun(int *p) {}
void fun(const int *p) {}
void fun(int &a) {}
void fun(const int &a) {}

7.注意函数调用的二义性;

如果在两个函数的参数表中,形参类型相同,而形参个数不同,形参默认值将会影响函数的重载

void fun(int a){}
void fun(int a,int b){}
void fun(int a ,int b = 10);

8.函数重载解析的步骤如下

  • 确定函数调用考虑的重载函数的集合, 确定函数调用中实参表的属性.
  • 从重载函数集合中选择函数 ,该函数可以在 (给出实参个数和类型 )的情况下可以调用函数.
  • 选择与调用最匹配的函数.

名字粉碎-名字修饰

“C”或者“C++”函数在内部(编译和链接)通过修饰名识别。修饰名是编译器在编译函数定义或者原型时生成的字符串。

修饰名由函数名、类名、调用约定、返回类型、参数等共同决定。

调用约定:

C调用约定(即用 __cdecl 关键字说明)按从右至左的顺序压参数入栈,由调用者把参数弹出栈。

对于传送参数的内存栈是由调用者来维护的(正因为如此,实现可变参数的函数只能使用该调用约

定)。

在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预编译(预处理)、编译、汇编、链

接。Name Mangling是一种在编译过程中,将函数名、变量名的名字重新命名的机制。

C 语言编译时函数名修饰约定规则

C语言的名字修饰规则非常简单,__cdecl是C/C++的缺省调用方式, 调用约定函数名字前面添加了下

划线前缀。

格式:_functionname

C++编译时函数名修饰约定规则:

__cdecl 调用约定:

1、以“?”标识函数名的开始,后跟函数名;

2、函数名后面以“@@YA”标识参数表的开始,后跟参数表;

3、参数表以代号表示:

X – void ,

D – char,

E – unsigned char,

F – short,

H – int,

I – unsigned int,

J – long,

K – unsigned long,

M – float,

N – double,

_N – bool,

PA-- 表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以“ 0 ”代替,一个“ 0 ”代表

一次重复;

4、参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前;

5、参数表后以“@Z”标识整个名字的结束,如果该函数无参数,则以“ Z ”标识结束。

//(?my_add_int@@YGHHH@Z)
int __stdcall my_add_int(int a, int b)
{
return a + b;
}
//(?print_int@@YAXH@Z)
void __cdecl print_int(int a)
{
printf("%d ", a);
}
// (?fun@@YIXXZ)
void __fastcall fun()
{
}
int main()
{
my_add_int(12, 23);
print_int(12);
fun();
return 0;
}

C++函数是重载

//(?my_max@@YAHHH@Z)
int my_max(int a, int b);
//(?my_max@@YADDD@Z)
char my_max(char a, char b);
//(?my_max@@YANNN@Z)
double my_max(double a, double b);
int main()
{
my_max(12, 23);
my_max('a', 'b');
my_max(12.23, 34.45);
return 0;
}

到此这篇关于C++深入讲解函数重载的文章就介绍到这了,更多相关C++函数重载内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++ 函数重载背后的原理

    目录 函数重载 函数重载的原理 为何C++可以支持重载 程序的编译链接 C语言为何不支持重载 C++为何可以支持函数重载 C++和C语言相互调用 创建静态库 C++调用C extern “C” extern “C” 原理 C语言调用C++ C++ 注意事项 extern "C"修饰的函数和一个函数完全一样 extern "C"修饰的函数和一个函数构成重载 函数重载 我们可能对函数很是熟悉,但是重载又是什么意思呢?我们先来用一个具体的场景来分享. 一天,张三的老板要你

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

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

  • C++中函数重载详解

    目录 函数重载的概念 函数重载的应用 为什么C++支持函数重载,而C语言不支持 函数重载的概念 函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的 形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题. 函数重载的应用 1.比如以下代码,函数名一样,而参数的类型不同,在调用的时候编译器会根据传递的参数自动进行匹配. 2.在例如以下代码,我们进行编译,都可以编译成功. 3.接下来看一个有趣的现象,将上述第二个例子

  • C++入门语法之函数重载详解

    目录 写在前面 1 函数重载的概念 2 函数重载原理 总结 写在前面 关于C语言的编译与链接不懂的可以看一下下面的文章,先回顾一下以前的知识. 详解C语言的编译与链接 1 函数重载的概念 函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题. //1.函数的参数个数不同 #include <iostream> using namespace std; void

  • C++超详细讲解函数重载

    目录 1 函数重载的定义 2 构成函数重载的条件 3 编译器调用重载函数的准则 4 函数重载的注意事项 4.1 避开重载带有指定默认值参数的函数 4.2 注意函数重载遇上函数指针 4.3 C++编译器不能以 C 的方式编译重载函数 1 函数重载的定义 函数重载:使用同一个函数名定义不同的函数.从本质上来看,就是互相独立的不同函数,每一个函数类型不同.因此,函数重载是由函数名和参数列表决定的. 注意:函数返回值不能作为函数重载的重要依据! 2 构成函数重载的条件 当满足以下三个条件之一时,便可以构

  • C++超详细分析函数重载的使用

    目录 一.函数重载分析(上) 1.1 重载的定义 1.2 函数重载的定义 1.3 函数重载需要满足的条件 1.4 编译器调用重载函数的准则 1.5 函数重载的注意事项 1.6 小结 二.函数重载分析(下) 2.1 函数重载遇上函数指针 2.2 C++和C的相互调用 2.3 使得C代码只会以C的方式被编译的解决方案 2.4 小结 一.函数重载分析(上) 1.1 重载的定义 定义:同一个标识符在不同的上下文有不同的意义 1.2 函数重载的定义 用同一个函数名定义不同的函数 当函数名和不同的参数搭配时

  • C++函数重载的定义与原因详解

    目录 引例 函数重载的定义 函数重载规则 为什么C不支持函数重载而C++可以 内部名称 总结 引例 如果要求你只能通过print函数,即能打印字符串,又能打印一个整型. 虽然在C语言中我们可以通过 print_i 和print_s来实现功能. 但是C++更方便.C++支持同一函数名,完成类似的功能的语法. void print(int i) { cout << "print a integer :" << i << endl; } void prin

  • C++简明讲解缺省参数与函数重载的用法

    目录 一.缺省参数 1.1缺省参数概念 1.2缺省参数分类 二.函数重载 2.1函数重载概念 2.2名字修饰 一.缺省参数 缺省参数形象来说就是"备胎". 1.1缺省参数概念 缺省参数是声明或定义函数时为函数的参数指定一个默认值.在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定的实参. #include<iostream> void P(int a = 3) { printf("%d", a); } int main() { P();//打印

  • C++深入分析回顾函数重载

    目录 一.函数重载回顾 二.类中的重载 三.重载的意义 四.小结 一.函数重载回顾 函数重载的本质为相互独立的不同函数 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; }

  • C++深入分析讲解函数与重载知识点

    目录 函数的默认(缺省)参数 1.默认参数的定义 2.默认参数的注意点 占位参数 1.占位参数 函数内部无法使用 2.占位参数 可以设置成缺省参数 函数重载 函数的默认(缺省)参数 1.默认参数的定义 c++在声明函数原型的时可为一个或者多个参数指定默认(缺省)的参数值,当函数调用的时候如果没有传递该参数值,编译器会自动用默认值代替. //函数的默认参数 指定x的默认值为10 y为20 int my_add(int x=10,int y=20) { return x+y; } void test

  • C++入门(命名空间,缺省参数,函数重载,引用,内联函数,auto,范围for)

    一.C++关键字 C++总共有63个关键字,在入门阶段我们只是大致了解一下就可,在后续博客中会逐渐讲解 二.命名空间 相信学过C++的同学,一定都写过下面这个简单的程序 #include<iostream> using namespace std; int main() { cout<<"hello world"<<endl; return 0; } 我们先来看第二行代码,using namespace std , 这行代码是什么意思呢 ? 这里我们

  • C++超详细讲解函数对象

    目录 一.客户需求 二.存在的问题 三.解决方案 四.函数对象 五.小结 一.客户需求 编写一个函数 函数可以获得斐波那契数列每项的值 每调用一次返回一个值 函数可根据需要重复使用 下面来看第一个解决方案: #include <iostream> using namespace std; int fib() { static int a0 = 0; static int a1 = 1; int ret = a1; a1 = a0 + a1; a0 = ret; return ret; } in

  • C++超详细讲解运算符重载

    目录 概念 赋值运算符重载 const成员 取地址及const取地址操作符重载 概念 C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类 型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似. 函数名字为:关键字operator后面接需要重载的运算符符号. 函数原型:返回值类型 operator操作符(参数列表) 需要注意的几点: 不能通过连接其他符号来创建新的操作符:比如operator@,必须是已有的操作符: 重载操作符必须有一个类类型

  • 通过实例理解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

随机推荐