资深流水灯工程师

资深流水灯工程师

我们知道C++可以对函数进行重载,让同名的函数来完成相同的基本操作。其实运算符也是可以重载的,而且有的运算符已经在使用了,就像*,既可以用于地址,又可以用于乘法。

运算符重载需要使用关键字operator

语法如下

Type operator Sign(const Type p1, const Type p2)
{
    Type ret;
    
    return ret;
}

 Sign指的是+   -    *   /  等操作符

复数类开发

如果我们需要计算两个复数的运算,就需要进行操作符重载了,因为常规的+ -不能直接进行复数运算。

#ifndef COMPLEX_H
#define COMPLEX_H


class Complex
{
private:
    int a;
    int b;
public:
    Complex();
    Complex(int a, int b);

    int getA();
    int getB();

    friend Complex operator+ (const Complex& p1, const Complex& p2);
};

Complex operator+ (const Complex& p1, const Complex& p2);

#endif // COMPLEX_H
#include "complex.h"

Complex::Complex(int a, int b)
{
    this->a = a;
    this->b = b;
}

Complex::Complex()
{
    a = 0;
    b = 0;
}



int Complex::getA()
{
    return a;
}


int Complex::getB()
{
    return b;
}


//+操作符重载,两个复数相加,实部与实部相加,虚部与虚部相加
//operator+相当于函数名,
//但是使用的时候直接使用+就可以
Complex operator+(const Complex& p1, const Complex& p2)
{
    Complex ret;

    ret.a = p1.a + p2.a;
    ret.b = p1.b + p2.b;

    return ret;

}

 

#include <iostream>
#include "complex.h"
using namespace std;


int main()
{
    Complex c1(1, 2);
    Complex c2(3, 4);

    //Complex c3 = operator+(c1,c2);
    Complex c3 = c1+c2; //与上面的语句等效

    cout <<" c3.getA():"<< c3.getA() << endl;
    cout <<" c3.getB():"<< c3.getB() << endl;

    return 0;
}

 分析:语句Complex c3 = operator+(c1,c2); 和语句Complex c3 = c1+c2;效果是一样的,本来复数是不能直接加减的,但是进行了+ 操作符重载,在进行复数运算是编译器法相不能直接+,就去看你有没有炒作符重载,有的话就直接拿来用。

上面的代码用的友元,在C++中友元是要慎用的,,可以将操作符重载函数直接定义为类的成员函数也是可以运行的,如下所示:

#ifndef COMPLEX_H
#define COMPLEX_H


class Complex
{
private:
    int a;
    int b;
public:
    Complex();
    Complex(int a, int b);

    int getA();
    int getB();

    Complex operator+(const Complex& p);
};


#endif // COMPLEX_H
#include "complex.h"

Complex::Complex(int a, int b)
{
    this->a = a;
    this->b = b;
}

Complex::Complex()
{
    a = 0;
    b = 0;
}



int Complex::getA()
{
    return a;
}


int Complex::getB()
{
    return b;
}


//+操作符重载,两个复数相加,实部与实部相加,虚部与虚部相加
//operator+相当于函数名,
//但是使用的时候直接使用+就可以
Complex Complex::operator+(const Complex& p)
{
    Complex ret;

    ret.a = this->a + p.a;
    //等效于ret.a = a + p.a;

    ret.b = this->b + p.b;
    //等效于ret.b = b + p.b;

    return ret;

}

友元函数与操作符重载函数对比

友元函数:friend Complex operator+ (const Complex& p1, const Complex& p2);

使用友源函数,需要左操作数p1和右操作数p2

类操作符重载函数:Complex operator+(const Complex& p);

使用类内部操作符重载函数,参数只有一个p,作为右操作数,左操作数就是本身this。

时间类开发

下面一个时间类,也进行时间的相关运算,时与时相加减,分钟与分钟相加减

#ifndef MYTIME_H
#define MYTIME_H

#include <iostream>

using namespace  std;

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);
    Time Sum(const Time& t) const;
    void Show() const;
};

#endif // MYTIME_H
#include "mytime.h"


Time::Time()
{
    hours = minutes = 0;
}

Time::Time(int h, int m)
{
    hours = h;
    minutes = m;
}

void Time::AddMin(int m)
{
    minutes += m;
    hours += minutes/60;
    minutes %= 60;
}

void Time::AddHr(int h)
{
    hours += h;
}

void Time::Reset(int h, int m)
{
    hours = h;
    minutes = m;
}

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;
}

void Time::Show() const
{
    cout << hours << " hours, " << minutes << " minutes.\n";
}
#include <iostream>
#include "mytime.h"

using namespace std;

int main()
{
    Time planning;
    Time coding(2, 40);
    Time fixing(5, 55);
    Time total;

    cout << "planning time = ";
    planning.Show();
    cout << endl;

    cout << "coding time = ";
    coding.Show();
    cout << endl;

    cout << "fixing time = ";
    fixing.Show();
    cout << endl;

    total = coding.Sum(fixing);
    cout << "coding.Sum(fixing) = ";
    total.Show();
    cout << endl;

    return 0;
}

输出结果

planning time = 0 hours, 0 minutes.

coding time = 2 hours, 40 minutes.

fixing time = 5 hours, 55 minutes.

coding.Sum(fixing) = 8 hours, 35 minutes.

添加加法运算符

将Time类转换为重载的加法运算法很容易,只要将Sum()的名称改为operator +()即可。只要把运算符+放在operator的后面

#ifndef STOCK_H
#define STOCK_H
#include <string>

using namespace std;

class stock
{
private:
    string company;
    long shares;
    double share_val;
    double total_val;
    void set_tot() {total_val = shares * share_val;}

public:
    void buy(long num, double price);
    void sell(long num, double price);
    void update(double price);
    void show() const;
    Time operator+(const Time& t) const;
    const stock& topval(const stock& s) const;

    stock(const string& co, long n, double pr);
    stock();
    ~stock();
};

#endif // STOCK_H
#include "mytime.h"


Time::Time()
{
    hours = minutes = 0;
}

Time::Time(int h, int m)
{
    hours = h;
    minutes = m;
}

void Time::AddMin(int m)
{
    minutes += m;
    hours += minutes/60;
    minutes %= 60;
}

void Time::AddHr(int h)
{
    hours += h;
}

void Time::Reset(int h, int m)
{
    hours = h;
    minutes = m;
}

//运算符+重载
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;
}

void Time::Show() const
{
    cout << hours << " hours, " << minutes << " minutes.\n";
}
operator+(const Time &t) const与Sum(const Time &t) const效果完全一样,可以理解operator+()就是一个函数,也可以被调用。就像下面的语句一样。
total = coding.operator+(fixing);

但是可以进一步简化

total = coding + fixing;

 这两种方法都讲使用operator+()函数,运算符左侧的coding是调用对象,右边的fixing是参数被传递的对象。

#include <iostream>
#include "mytime.h"

using namespace std;

int main()
{
    Time planning;
    Time coding(2, 40);
    Time fixing(5, 55);
    Time total;

    cout << "planning time = ";
    planning.Show();
    cout << endl;

    cout << "coding time = ";
    coding.Show();
    cout << endl;

    cout << "fixing time = ";
    fixing.Show();
    cout << endl;


    //total = coding.operator+(fixing);
    total = coding + fixing;
    cout << "coding.Sum(fixing) = ";
    total.Show();
    cout << endl;

    return 0;
}

输出结果没有变化

planning time = 0 hours, 0 minutes.

coding time = 2 hours, 40 minutes.

fixing time = 5 hours, 55 minutes.

coding.Sum(fixing) = 8 hours, 35 minutes.

 运算符重载的限制:

1、重载后的运算符必须至少有一个操作数是用户定义的类型;

2、使用运算符使不能违反运算符原来的句法规则;

3、不能创建新的运算符;

4、有些运算符不能被重载:如sizeof, ?:, ::等

5、大多数运算符都可以通过成员或者非成员函数进行重载,但=、()、[]、->只能通过成员函数进行重载。

+ 、-、 *重载的应用

#ifndef MYTIME_H
#define MYTIME_H

#include <iostream>

using namespace  std;

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);
    Time operator+(const Time& t) const;
    Time operator-(const Time& t) const;
    Time operator*(double mult) const;
    void Show() const;
};

#endif // MYTIME_H
#include "mytime.h"


Time::Time()
{
    hours = minutes = 0;
}

Time::Time(int h, int m)
{
    hours = h;
    minutes = m;
}

void Time::AddMin(int m)
{
    minutes += m;
    hours += minutes/60;
    minutes %= 60;
}

void Time::AddHr(int h)
{
    hours += h;
}

void Time::Reset(int h, int m)
{
    hours = h;
    minutes = m;
}

//运算符+重载
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;
}

Time Time::operator-(const Time& t) const
{
    Time diff;
    int tot1, tot2;
    tot1 = t.minutes + 60 * t.hours;
    tot2 = minutes + 60 * hours;
    diff.minutes = (tot2 - tot1) % 60;
    diff.hours = (tot2 - tot1) / 60;

    return diff;
}


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;
}

void Time::Show() const
{
    cout << hours << " hours, " << minutes << " minutes.\n";
}
#include <iostream>
#include "mytime.h"

using namespace std;

int main()
{
    Time weeding(4, 35);
    Time waxing(2, 47);

    Time total;
    Time diff;
    Time adjusted;

    cout << "weeding time =  ";
    weeding.Show();
    cout << endl;

    cout << "waxing time =  ";
    waxing.Show();
    cout << endl;

    cout << "total working time =  ";
    total = weeding + waxing;
    total.Show();
    cout << endl;

    diff = weeding - waxing;
    cout << "weeding time - waxing time = ";
    diff.Show();
    cout << endl;

    adjusted = total * 1.5;
    cout << "adjusted work time = ";
    adjusted.Show();
    cout << endl;

    return 0;
}

输出结果

weeding time =  4 hours, 35 minutes.

waxing time =  2 hours, 47 minutes.

total working time =  7 hours, 22 minutes.

weeding time - waxing time = 1 hours, 48 minutes.

adjusted work time = 11 hours, 3 minutes.
10-27 20:22