重载/友元

  重载分为函数重载和运算符重载!重载本身的概念在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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章