函数重载,傻傻分不清

858 阅读3分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

本文介绍的是C++的函数重载

前言:

函数重载的意思是如果同一作用域的几个函数名字相同但形参列表不同,我们称之为函数重载。

简单地说就是函数名相同,但参数不同,不看返回值类型;但真正细节的说其实是函数签名不同

1、全局函数重载

函数重载依据的是形参列表,示例如下:

void AA(int x){}
void AA(int x,int y){}

上述示例两个函数参数列表不同,即函数签名不同,是两个同名但不同的函数;

上细节:

细节一:函数重载与返回值无关

返回值不属于函数签名部分,因此系统无法识别两个函数,编译器会提示错误

函数签名定义:包含了一个函数的信息,包括函数名、参数类型、参数个数、顺序以及它所在的类和命名空间。

image-20210805205109593.png

细节二:与有无形参名无关

示例:

void AA(int x){}
void AA(int){}

二者函数签名,是相同函数

细节三:typedef重写类型无法重载

示例:

typedef int int_32
void AA(int x){}
void AA(int_32 x){}

二者函数签名,是相同函数,看起来二者形参不同,但int_32不是新类型,他只是int别名,本质上没有什么不同,所以不发生重载

细节四:重载与const形参

顶层const不影响传入参数对象,一个拥有顶层const形参无法和一个没有顶层const的形参区别开;

示例:

void AA(const int x){}
void AA(int x){}

void BB(int *x){}
void BB(int * const x){}

编译器无法区别二者形参,因为声明是相同的,即函数签名相同

底层const形参与非底层const形参可以发生重载,通过区分是常量对象还是非常量对象来区分函数

示例:

void AA(const int &x){}//引用
void AA(int &x){}//常量引用

void BB(int *x){}//指针
void BB(const int *x){}//指向常量的指针

上述实例中,编译器可以冲过实参是否为常量来推断调用哪个函数。因为const不能转换为其他类型,所以我们只能把const对象(或指向const的指针)传递给const形参。上面四个函数都可传非常量,不过传递非常量或者非常量指针编译器会优先选择非常量版本。

细节五:占位参数与默认参数

示例:

void pp(int x,int=0){//一
    printf("int\n");
}
void pp(int x,int y=0){//二
    printf("y\n");
} 
void pp(int x){//三
    printf("x\n");
}

一与二不能重载(完全不能重载),一与不能重载(在只调用一个参数时),二与三也不能重载(在只调用一个参数时)

2、成员函数重载

成员函数重载几乎和全局函数没有区别,但有一个全局函数不存在的细节

细节:函数名尾部的const是函数签名的一部分,算作函数重载

示例:

#include <iostream>
using namespace std;
class A
{
private: 
	int a;
	int b;
public:
        A(){};
	void AA(int a,int b)//一
	{
                printf("V");
    }
	void AA(int a,int b) const// 二
	{
		a=1;
		b=1;
                printf("*");
	}
}; 
int main(int  argc ,const char  **argv)
{
        const A C;
        A B;
        C.AA(1,2);
        B.AA(1,2);
		return 0;
}

输出:*v

一函数代表输入调用该函数对象类型可以是常量也可以是变量,二函数代表调用该函数对象类型只可以是常量,但二者同时存在编译器会自动区分开来,常量调用的是二函数,变量调用的是一函数