重载分为函数重载和运算符重载!重载本身的概念在C++中通俗含义是:相同的某个元素表达不同的意思!我们首先来看函数重载。
函数重载
函数重载本身时比较简单明了的,即定义同一个函数名称,通过设置不同的传入参数来使之成为不同的函数!如下所示:
Time();
Time(int h, int m = 0);
在类声明中声明同一个函数名称Time(注意,这是个特殊的函数,我们称之为构造函数,即创建对象时,将自动调用此成员函数),但是由于第一个函数,默认没有参数,第二个函数默认传入参数h,m。所以,我们在使用此函数名称时,编译器会根据函数的形式,自动匹配相应的函数是现!如我们创建一个对象:
Time planing;
可以看到,没有传递任何参数,所以编译器调用默认构造函数,即
Time()
我们如果再创建一个对象:
Time coding(2,40);
显然,这里将调用第二个构造函数,即
Time(int h,int m);
关于编译器如何匹配重载函数,建议阅读如下文章:吴秦:C++的函数重载。希望对构造函数能够有深刻的理解!
有的人说了,为什么要整出个重载呢? 试想想,如果你要实现n个相似的功能的函数,而要定义n个不同名称的函数是个多么混乱和复杂的事情。重载函数的存在就是为了简化此类函数的定义。
再来看看运算符重载!
运算符重载
我们举个例子,假如定义一个类TIME,包含两个私有变量hour,minutes。如下所示:
class Time
{
private:
int hours;
int minutes;
public:
Time();
Time(int h, int m = 0);
void AddMin(int m);
void AddHr(int h);
void Reset(int h = 0, int m = 0);
const Time Sum(const Time & t) const;
void Show() const;
};
如果现在有两个对象,我们需要求两个对象a和b中这两个变量的和,那么通常的做法是直接通过对象a.hours+a.hours,a.min+b.min即可以实现,那么可不可以直接a+b呢?答案显然是不可以的,那我们有方法让他们直接想加吗?有!这就需要运算符重载,即拓展运算符的功能!事实上,我们在C语言也见到过如:
c+=1;
其本身就可以理解成“+”号重载的例子!这里我们稍微拓展一下比如:”2h15min+1h50min”我们该如何实现?
我们首先把它写成普通的类函数实现:
const Time Time::Sum(const Time & t) const
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum;
}
然后,通过运算符重载来实现这个函数!所以我们不得不“祭出”运算符重载的关键字“opertor”。转换的函数实现如下:
Time Time::operator+(const Time & t) const
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum;
}
注意到,函数实现本身并没有发生变换,只不过把原来的sum改为opertor+,所以,理论上我们依然可以通过普通调用方式:
total=a.operater+(b);
来调用此函数,然而一个更合适的方式是直接省略opertor,而写成:
total=a+b;
注意:重载运算符左侧的对象是调用对象,即默认的对象函数本身,重载运算符右边的对象是传入的对象的参数——这是一个编译器默认的规则,必须遵守!
根据这个例子,我们当然可以定义opertor-,opertor*等语法允许的重载运算符!(c++在重载运算符的定义中会有相应的限制,如不能定义opertor+为“减”功能,等等!建议在使用中再注意查询!)如下:
Time operator+(const Time & t) const;
Time operator-(const Time & t) const;
Time operator*(double n) const;
我们注意到有一个重载运算符是 opertor*,它使得我们可以做出
coding*1.5
这种——即不同数据类型的相运算的方式,如前所述不能写成
1.5*coding
因为1.5并不是opertor*所属类的成员变量!那么有没有什么替代方法呢?有!我们可以定义一个非成员函数来解决类似的问题:
Time opertor*(int multi,Time & t );
但是,我们会面临另一个问题:即非成员函数是不能访问成员函数内部的私有变量!于是就引入了一个新的概念:友元函数!
友元函数
友元函数的创建方法如下:
friend Time operator*(double m, const Time & t)
{ return t * m; }
这样,我们就可以在该函数中调用私有变量,即当我们写出:
A=2.75*B
将被解释为:
A=operater*(2.75,B)