一、函数重载(Function Overloading)
C++ 允许多个函数拥有相同的名字,只要它们的参数列表不同就可以,这就是函数的重载(Function Overloading)。借助重载,一个函数名可以有多种用途。
例:借助函数重载交换不同类型的变量的值
#include <iostream>using namespace std;//交换 int 变量的值void Swap(int *a, int *b){int temp = *a;*a = *b;*b = temp;}//交换 float 变量的值void Swap(float *a, float *b){float temp = *a;*a = *b;*b = temp;}//交换 char 变量的值void Swap(char *a, char *b){char temp = *a;*a = *b;*b = temp;}//交换 bool 变量的值void Swap(bool *a, bool *b){char temp = *a;*a = *b;*b = temp;}int main(){//交换 int 变量的值int n1 = 100, n2 = 200;Swap(&n1, &n2);cout<<n1<<", "<<n2<<endl;//交换 float 变量的值float f1 = 12.5, f2 = 56.93;Swap(&f1, &f2);cout<<f1<<", "<<f2<<endl;//交换 char 变量的值char c1 = 'A', c2 = 'B';Swap(&c1, &c2);cout<<c1<<", "<<c2<<endl;//交换 bool 变量的值bool b1 = false, b2 = true;Swap(&b1, &b2);cout<<b1<<", "<<b2<<endl;return 0;}
当实参的类型和形参的类型不一致时情况就会变得稍微复杂,要注意重载过程中的二义性和类型转换。请参考http://c.biancheng.net/view/vip_2207.html
二、运算符重载(Operator Overloading)
实际上,我们已经在不知不觉中使用了运算符重载。例如,+号可以对不同类型(int、float 等)的数据进行加法操作;<<既是位移运算符,又可以配合 cout 向控制台输出数据。C++本身已经对这些运算符进行了重载。C++ 也允许程序员自己重载运算符,这给我们带来了很大的便利。
运算符重载的格式为:
返回值类型 operator 运算符名称 (形参表列){//TODO:}
operator是关键字,专门用于定义重载运算符的函数。我们可以将operator 运算符名称这一部分看做函数名,对于下面的代码,函数名就是operator+。运算符重载是通过函数实现的,它本质上是函数重载。
1)重载+
例:复数类的+重载:
#include <iostream>
using namespace std;
class complex{
public:
complex();
complex(double real, double imag);
public:
//声明运算符重载
complex operator+(const complex &A) const;
void display() const;
private:
double m_real; //实部
double m_imag; //虚部
};
complex::complex(): m_real(0.0), m_imag(0.0){ }
complex::complex(double real, double imag): m_real(real), m_imag(imag){ }
//实现运算符重载
complex complex::operator+(const complex &A) const{
complex B;
B.m_real = this->m_real + A.m_real;
B.m_imag = this->m_imag + A.m_imag;
return B;
}
void complex::display() const{
cout<<m_real<<" + "<<m_imag<<"i"<<endl;
}
int main(){
complex c1(4.3, 5.8);
complex c2(2.4, 3.7);
complex c3;
c3 = c1 + c2;
c3.display();
return 0;
}
运行结果:6.7 + 9.5i
上面的例子中,我们在 complex 类中重载了运算符+,该重载只对 complex 对象有效。当执行c3 = c1 + c2;语句时,编译器检测到+号左边(+号具有左结合性,所以先检测左边)是一个 complex 对象,就会调用成员函数operator+(),也就是转换为下面的形式:
c3 = c1.operator+(c2);
将运算符重载函数作为全局函数时,一般都需要在类中将该函数声明为友元函数。原因很简单,该函数大部分情况下都需要使用类的 private 成员。
如上面的例子,若重载函数为全局函数:
complex operator+(const complex &A) const{
complex B;
B.m_real = this->m_real + A.m_real;
B.m_imag = this->m_imag + A.m_imag;
return B;
}
对应的类中函数声明变成:
//声明为友元函数
friend complex operator+(const complex &A, const complex &B);
到底以成员函数还是全局函数(友元函数)的形式重载运算符,请参考http://c.biancheng.net/view/vip_2310.html
要以全局函数的形式重载 +、-、、/、==、!=,以成员函数的形式重载了 +=、-=、=、/=
2)重载()(函数调用运算符)
函数调用运算符 () 可以被重载用于类的对象。当重载 () 时,不是创造了一种新的调用函数的方式,相反地,这是创建一个可以传递任意数目参数的运算符函数。
例1:(仿函数)
#include <iostream>
using namespace std;
class Time
{
public:
//小括号重载 版本0
void operator()()
{
cout<< "version 0"<<endl;
}
//小括号重载 版本1
void operator()(int h)
{
cout<< "version 1"<<endl;
}
//小括号重载 版本2
void operator()(int h, int m)
{
cout<< "version 2"<<endl;
}
};
int main()
{
Time t;
t(); //小括号重载 版本0
t(1); //小括号重载 版本1
t(1,1); //小括号重载 版本2
return 0;
}
例2:
#include <iostream>
using namespace std;
class Distance
{
private:
int feet; // 0 到无穷
int inches; // 0 到 12
public:
// 所需的构造函数
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
// 重载函数调用运算符
Distance operator()(int a, int b, int c)
{
Distance D;
// 进行随机计算
D.feet = a + c + 10;
D.inches = b + c + 100 ;
return D;
}
// 显示距离的方法
void displayDistance()
{
cout << "F: " << feet << " I:" << inches << endl;
}
};
int main()
{
Distance D1(11, 10), D2;
cout << "First Distance : ";
D1.displayDistance();
D2 = D1(10, 10, 10); // invoke operator()
cout << "Second Distance :";
D2.displayDistance();
return 0;
}
结果:
First Distance : F: 11 I:10
Second Distance :F: 30 I:120
