运算符重载和友元函数

Posted feng-ying

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了运算符重载和友元函数相关的知识,希望对你有一定的参考价值。

1. 运算符重载

c++允许将运算符重载扩展到用户定义的类型,例如:允许使用+将两个对象相加,编译器将根据操作数的数目和类型决定使用哪种加法定义,重载运算符可以使代码看起来更加自然。

例:计算时间,一个运算符重载的实例:

class Time {
private:
    int hours;
    int minutes;
public:
    Time() {}
    Time(int hours, int minutes) {
        this->hours = hours;
        this->minutes = minutes;
    }

    void setHours(int hours) {
        this->hours = hours;
    }

    int getHours() {
        return this->hours;
    }

    void setMinutes(int minutes) {
        this->minutes = minutes;
    }

    int getMinutes() {
        return this->minutes;
    }

    Time operator+(const Time& t) const {
        Time sum;
        sum.minutes = t.minutes + this->minutes;
        sum.hours = t.hours + this->hours + sum.minutes / 60;
        sum.minutes = sum.minutes % 60;
        return sum;
    }

    Time operator*(double mult) const {
        Time result;
        long totalMinutes = hours * mult * 60 + minutes * mult;
        result.hours = totalMinutes / 60;
        result.minutes = totalMinutes % 60;
        return result;
    }
};

测试:

技术图片

2. 友元函数

 运算符重载中,下面的语句

A = B * 3.5

将被转成下面的成员函数调用

A = B.operator*(3.5)

但是下面的语句又会如何呢

A = 3.5 * B;  // cannot correspond to a member function

解决这个问题的一种方式是,告诉每个人,只能按照B * 3.5这种格式编写,这是一种对服务器友好-客户警惕的解决方案,与OOP无关

还有一种方式:非成员函数,非成员函数不是由对象调用的,它使用的所有值都是显式参数,这样编译器能够将下面的表达式

A = 3.5 * B

与非成员函数匹配

A = operator*(3.5, B);

该函数的原型如下:

Time operator*(double m, const Time& t);对于非成员重载运算符函数而言,运算符左边的操作数等于操作符函数的第一个参数,运算符表达式右边的操作数对应于运算符函数的第二个参数。

使用非成员函数可以按照所需的顺序获得操作数,但是引发了一个新的问题,非成员函数不能直接访问类的私有数据,至少常规非成员函数不能访问,然而有一类特殊的非成员函数可以访问类的私有成员,被称为友元函数

创建友元函数的额第一步是将函数原型放在类的声明中,并在原型的声明前加上关键字friend

friend Time operator*(double m, const Time& t);

该原型意味着两点:

1. 虽然operator*()函数都是在类声明中声明的,但是不是成员函数,因此不能使用成员运算符来调用;

2. 虽然operator*()函数不是成员函数,但是它与成员函数的访问权限相同

第二步是编写函数的定义,因为它步是成员函数,所以不需要使用Time::限定符

以上是关于运算符重载和友元函数的主要内容,如果未能解决你的问题,请参考以下文章

从一个二级题来看成员函数重载运算符和友元函数重载运算符

运算符重载和友元

类和对象——补充(运算符重载,static和explicit关键字和友元,内部类)

关于C++运算符重载和友元的概念

运算符重载的函数作为类的成员函数和友元函数

C++运算符重载中 重载为类的成员函数和重载为类的友元函数 的区别是啥?