C++

运算符重载写法

类似与定义函数一样,只是把函数名变成operator 运算符

例:

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

1. 类中运算符重载

通过在类中定义成员函数实现:

class Time{
private:
    int hours;
    int minutes;
public:
    Time(){hours = 0, minutes = 0;};
    Time(int h, int m = 0): hours(h), minutes(m){};
    Time operator*(double mult) const; // 别忘加 const
    void show() const {cout << hours << ":" << minutes << endl;};
};

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

上面程序中实现的运算符重载,可以做如下使用:

Time A(1, 2);
Time B = A * 2;
B.show()// 2:4

注意:以上不可以写成: B = 2 * A;,这样写是错误的,无法通过编译。

因为B = A * 2;被编译器转换成了成员函数调用:B = A.operator*(2) ;而B = 2 * A中的2不是对象,编译器无法使用类成员函数进行转换。如果要解决以上出现问题,就要使用接下要介绍的友元函数重载。

2. 友元函数重载

通过在类中声明Time operator*(double mult, const Time &t)是友元函数:

注意:

  • 虽然operator*()在类中声明了,但它不是成员函数,因此不能使用成员函数运算符调用。
  • 虽然operator*()不是成员函数,但是它与成员函数的访问权限相同。
class Time{
private:
    int hours;
    int minutes;
public:
    Time(){hours = 0, minutes = 0;};
    Time(int h, int m = 0): hours(h), minutes(m){};
    friend Time operator*(double mult, const Time &t);
    void show() const {cout << hours << ":" << minutes << endl;};
};

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

上面程序中实现的运算符重载,可以做如下使用:

Time A(1, 2);
Time B = 2 * A;
B.show(); //2:4

注意:以上不可以写成: B = A * 2;,这样也不行。如果既要用B = A * 2B = 2 * A,可以把类中运算符重载和友元重载结合使用。

因为B = 2 * A;被编译器转换成了:B = operator*(2, A) , 从而调用刚刚定义的非成员友元函数。

B = A * 2B = 2 * A一起使用:

#include <iostream>
using namespace std;

class Time{
private:
    int hours;
    int minutes;
public:
    Time(){hours = 0, minutes = 0;};
    Time(int h, int m = 0): hours(h), minutes(m){};
    friend Time operator*(double mult, const Time &t);
    Time operator*(double mult) const;
    void show() const {cout << hours << ":" << minutes << endl;};
};

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

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


int main() {
    Time A(1, 2);
    Time B = 2 * A;
    B.show(); // 2:4
    Time C = A * 3;
    C.show(); // 3:6
    return 0;
}

重载 << 运算符

第1种方法

friend void operator<<(ostream &os, const Time &t); // 先在类中声明;

void operator<<(ostream &os, const Time &t) {
    os << t.hours << " hours, " << t.minutes << " minutes";
}

// 使用
trip(4, 23);
cout << trip;// 4 hours, 23 minutes

注意:通过这种重载方法之后,cout << 不能像平时那样正常使用了,比如cout << trip << "test1234" << endl这样写就会报错。接下来介绍第2种方法来解决此问题。

第2种方法

friend ostream& operator<<(ostream &os, const Time &t); // 先在类中声明;

ostream& operator<<(ostream &os, const Time &t) {
    os << t.hours << " hours, " << t.minutes << " minutes\n";
    return os;
}

// 使用
trip(4, 23);
cout << trip << " test1234" << endl;// 4 hours, 23 minutes test1234

附——友元声明

1. 友元函数

class A{
private:
    int n;
public:
    friend void test(int x, A &a);
};

void test(int x, A &a) {
    a.n = x;
    cout << "num: " << a.n << endl;
}

2. 友元类

class A{
private:
    int n;
public:
    friend class B;
};

class B{
private:
    int t;
public:
    void test(int x, A &a) {
        a.n = x;
        cout << "num: " << a.n << endl;
    }
};

3. 友元类成员函数

class A; // 要先定义class A
class B{
private:
    int t;
public:
    void test(int x, A &a); // 在外部实现,不能在内部实现
};

class A{
private:
    int n;
public:
    friend void B::test(int x, A &a);
};

void B::test(int x, A &a) {
    a.n = x;
    cout << "num: " << a.n << endl;
}
This is just a placeholder img.