重载

大多数编程语言规定每个函数只能有唯一的标识符。如果想打印三种不同类型的数据:整型、字符型和实型,则不得不用三个不同的函数名,如Print_int( )、Print_char( )、Print_float( )
函数重载是指两个或两个以上的函数具有相同的函数名,但参数类型不一致或参数个数不同。编译器根据实参和形参的类型及个数进行相应地匹配,自动确定调用哪一个函数。使得重载的函数虽然函数名相同,但功能却不完全相同。
函数重载是C++对C语言的扩展,包括非成员函数的重载和成员函数重载

非成员函数重载

非成员函数重载是指对用户所编写的那些功能相同或类似、参数个数或类型不同的用户自定义函数,从而提高程序的可读性(C++特有)。
支持函数重载是C++多态性的体现之一。
注意 :
1、重载函数函数名相同,但必须具有不同的参数个数或不同的参数类型,若只是返回值的类型不同或形参名不同是不行的。
例如:
void mul (int x,int y); int mul (int x,int y); //错误,编译器不以返回值来区分函数
int mul (int x,int y); int mul (int a,int b); //错误,编译器不以形参名来区分函数
2、匹配重载函数的顺序:寻找一个严格的匹配,如果能找到,调用该函数;通过内部类型转换寻求一个匹配,如果能找到,调用该函数;通过强制类型转换寻求一个匹配,如果能找到,调用该函数。
3、不要将不同功能的函数定义为重载函数,以免产生误解。
例如: int f(int a,int b){ return a+b;}
double f(double a,double b){ return ab;}
4、创建重载函数时,必须让编译器能区分两个(或更多)的重载函数,当创建的多个重载函数编译器不能区分时,编译器就认为这些函数具有多义性,这些函数调用是错误的,编译器不会编译该程序。 *(避免二义性)

举例说明

  1. - 当函数的重载带有默认参数时,要避免产生二义性。

成员函数重载

成员函数的重载主要是为了适应相同成员函数的参数多样性。成员函数重载的一个很重要的应用就是重载构造函数。在解决实际问题时,可能会需要创建具有不同形态的对象,例如,创建一个对象时可能需要带参数,也可能不需要带参数,或是带的参数的个数不一样。解决这些问题就需要用到C++提供的函数的重载机制。通过对构造函数进行重载,可以实现定义对象时初始化赋值的多样性。但是析构函数不能重载,因为一个类中只允许有且仅有一个析构函数。

class testClass {
public :
    testClass();//第一种不带参数的默认构造函数---------
    testClass(int a, char b);//构造函数
    testClass(int a = 0, char b = 'c');//参数都有默认值的默认构造函数-------

private:
    int m_a;
    char m_b;
};

默认参数

默认参数允许在函数的声明或定义时给一个或多个参数指定默认值。这样在进行调用时,如果不给出实际参数,则可以按指定的默认值进行工作
image.png
说明:
1、 当函数既有原型声明又有定义时,默认参数只能在原型声明中指定,而不能在函数定义中指定,例如:
image.png
2、在函数原型中,所有取默认值的参数都必须出现在不取默认值的参数的右边。也就是一旦开始定义默认值的参数,在其后面就不能再说明不取默认值的参数了。
void fun(int i,int j=5,int k); //错误、在默认j=5后,就不能再说明非默认参数int k。
应改为:void fun(int i,int k,int j=5);
3、在函数调用时,若某个参数省略,则其后的参数皆应省略而采用默认值。不允许某个参数省略后,再给其后的参数指定参数值,例如:
Complex( ,9.6); //错误的调用
4、当函数的重载带有默认参数时,要注意避免二义性。例如:
Complex(double r,double i=0);
Complex(double r);是错误的。如果有函数调用Complex(3.5)时,编译器将无法确定调用哪一个函数。
5、 函数的带默认参数值的功能可以在一定程度上简化程序的编写。如构造函数的重载(三个函数)就可以写成一个。

#include<iostream>
#include<math.h>
using namespace std;
class point{
private:
    int x,y;
public:
    point(int x1=0,int y1=0);        三个构造函数可以写成一个
    double distance(point p);        
};
point::point(int x1,int y1)
{
    x=x1;
    y=y1;
}
double point::distance(point p)
{
    double d;
    d=sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));//隐式使用this指针
    return d;
}
int main()
{
    point p1(3,4),p2;
    cout<<"distance="<<p1.distance(p2)<<endl;
    return 0;
}