C++函数重载

函数重载定义:可以有多个同名的函数。可以使用函数重载来设计一系列函数-----它们完成相同的工作,但使用不同的参数列表。

函数重载的关键是函数的参数列表----也称为函数特征标(funtion signature).如果两个函数的参数数目和类型相同,同时参数的排列顺序也相同,则它们的特征标相同,而变量名是无关紧要的。C++允许定义名称相同额函数,条件是它们的特征标不同。如果参数数目或者参数类型不同,则特征标也不同。

【示例】定义一组原型如下的printf()函数:

 void printf(const char * str,int width);  #1
 void printf(double d,int width);           #2
 void printf(long k,int width);             #3
 void printf(int i,int width);              #4
 void printf(const char *str);              #5
    

使用printf()函数时,编译器将根据所采取的用法使用有相应特征标的原型:

printf("hello",15);           #1
printf("hello");              #5
printf(1000.0,15);            #2
printf(1000,15);              #4
printf(1000.L,15);            #3

例如:printf(“hello”,15); 使用一个字符串和一个整数作为参数,这与#1原型匹配。

使用被重载的函数时,需要在函数调用中使用正确的参数类型。例如:

unsigned int y=100;
printf(y,6);          //ambiguous call

printf()调用与哪个原型匹配呢?它不与任何原型匹配!没有匹配的原型并不会自动停止使用其中的某个函数,因为C++将尝试使用标准类型转换强制进行匹配。如果#2原型是printf()唯一的原型,则函数调用printf(y,6)将把y转换为double类型。但是在上面的代码中,有三个将数字作为第一个参数的原型,因此有三种转换y的方式。在这种情况下,C++将拒绝这种函数调用,并将其视为错误。

一些看起来彼此不同的的特征标是不能共存的。例如:

double cube(double x);
double cube(double & x);

这里不构成重载。从编译器的角度来考虑这个问题。
假如有这样的代码:

cout<<cube(x);

参数x与double x 原型和double &x原型都匹配。因此编译器无法确定究竟应使用哪个原型。为避免这种混乱,编译器在检查函数特征标时,将把类型引用和类型本身视为同一个特征标

匹配函数时,并不区分const 和非const 变量。请看下面的原型:

void f(char *p);               #1
void f(const char * p)         #2
void y(char *p)                #3
void k(const char * p)         #4

下面列出了各种函数调用相应的原型:

cosnt char p1[20]="hell world";
char p2[20]="good ";
f(p1);              #2
f(p2);              #1
y(p1);              #no match
y(p2);              #1
k(p1);              #4
k(p2);              #4

f()函数原型有两个原型,一个用于const指针,另一个用于常规指针,编译器将根据实参是否为const来决定使用哪个原型。y()函数只与非const 参数的调用匹配,而k()函数可以与带const 或非const 参数的调用匹配。y()和k()之所以在行为上有这种差别,主要是由于将非const值赋给const变量是合法的,但反之是非法的。(范围可以缩小,不可以放大)。

函数的重载的规则:

  • 函数名称必须相同。
  • 参数列表必须不同(个数不同、类型不同、参数排列顺序不同等)。
  • 函数的返回类型可以相同也可以不相同。
  • 仅仅返回类型不同不足以成为函数的重载。

不可以构成重载的情况:

  • 静态函数声明(static)

  • 参数是引用的类型,要根据实参的情况来定

         实参为常量时,可以重载
         实参为变量时,不可以重载
        一般而言,引用不作为重载的条件
    
  • 参数是const的类型,也要根据具体情况分析

        如果是const普通类型,则不可形成重载
        如果是const指针类型,则可以形成重载
    

C++ 是如何做到函数重载的

C++代码在编译时会根据参数列表对函数进行重命名,例如 void Swap(int a, int b) 会被重命名为 _Swap_int_intvoid Swap(float x, float y) 会被重命名为 _Swap_float_float 。当发生函数调用时,编译器会根据传入的实参去逐个匹配,以选择对应的函数,如果匹配失败,编译器就会报错,这叫做 重载决议( Overload Resolution ) 。
不同的编译器有不同的重命名方式,这里仅仅举例说明,实际情况可能并非如此。
从这个角度讲,函数重载仅仅是语法层面的,本质上它们还是不同的函数,占用不同的内存,入口地址也不一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值