正常实现

  1. class Time {
  2. public:
  3. Time(int h, int m, int s) : h(h), m(m), s(s){}
  4. Time operator+(const Time& rhs) const {
  5. int h = this->h + rhs.h;
  6. int m = this->m + rhs.m;
  7. int s = this->s + rhs.s;
  8. if (s > 60) {
  9. m += s / 60;
  10. s %= 60;
  11. }
  12. if (m > 60) {
  13. h += m / 60;
  14. m %= 60;
  15. }
  16. return Time(h, m, s);
  17. }
  18. Time &operator+=(const Time& rhs) {
  19. *this = *this + rhs;
  20. return *this;
  21. }
  22. int h, m, s;
  23. };

+= 重载函数使用了一次构造函数,如果使用下面方法去实现可以省去一次构造,直接在 this 的成员上进行构造。

  1. Time &operator+=(const Time& rhs) {
  2. h += rhs.h;
  3. m += rhs.m;
  4. s += rhs.s;
  5. if (s > 60) {
  6. m += s / 60;
  7. s %= 60;
  8. }
  9. if (m > 60) {
  10. h += m / 60;
  11. m %= 60;
  12. }
  13. return *this;
  14. }
  15. Time operator+(const Time& rhs) const {
  16. Time t(*this);
  17. t += rhs;
  18. return t;
  19. }

+重载不应该修改 this ,由于+法重载无论如何都会进行一次构造,所以我们通常手动实现+=重载(在this上构造,+=需要改变this),再由+=实现+重载(需要新的对象)。

  1. Time operator+(const Time& lhs, const Time& rhs) {} // 也可以抽出来当作自由函数

自增操作符重载

  1. Time operator++(int) {
  2. Time t(*this);
  3. ++(*this);
  4. return t;
  5. }
  6. Time& operator++() {
  7. ++s;
  8. if (s > 60) {
  9. ++m;
  10. s %= 60;
  11. }
  12. if (m > 60) {
  13. ++h;
  14. m %= 60;
  15. }
  16. return *this;
  17. }

分别对应 a++,++a,int 主要是为了区分两种自增,由于 a++ 返回的是增加之前的,所以需要额外构造出一个对象。

注意为什么 a++ 的返回类型是 Time 是因为 t 是局部变量,无法取引用 Reference to stack memory associated with local variable ‘t’ returned 。由于 *this 是在上层作用域存储的,所以可以返回 Time& 类型。

  1. friend std::ostream &operator<<(std::ostream& os, const Time& t) {
  2. os << t.h << ":" << t.m << ":" << t.s;
  3. return os;
  4. }

二元操作符

经常会有Overloaded 'operator<<' must be a binary operator (has 3 parameters) 报错,如果你重载了二元操作符,如果在类内部使用了下面写法,则提示上面报错。是因为类内部隐藏传递了 this 参数,所以有三个参数。将下面的重载写在类外部即可。

  1. std::ostream &operator<<(std::ostream& os, const Time& t) {
  2. os << t.h << ":" << t.m << ":" << t.s;
  3. return os;
  4. }