我们知道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
- #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
-
- 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
- #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
-
- 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
- #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
-
- 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
- #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.