C++中的运算符重载

本文详细介绍了C++中的运算符重载技术,它是如何使对象操作更加直观的。通过实例展示了如何在自定义类Time中重载加法运算符,使得两个时间对象可以相加。此外,还解释了为何在某些情况下需要使用友元函数来重载运算符,如乘法运算符,并提供了实现友元重载乘法运算符的代码。最后,讨论了如何重载输出流运算符<<,以方便显示对象的内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.概念

运算符重载是一种使对象操作更加美观的技术,可以将运算符重载理解为语法糖。运算符重载将函数重载的概念扩展到运算符上,赋予C++运算符更多含义。例如,将*用于地址,可获取这个地址中的值,将*用于两个数字,可获取两个数字的乘积

C++可将运算符重载扩展到用户定义的类型,例如,允许使用+将两个对象相加,编译器根据操作数的数目和类型决定使用哪种加法定义,运算符重载使代码更加自然、容易理解

要重载运算符,需使用被称为运算符函数的特殊函数形式,格式:operatorop(argument-list)

2.例子

两个非基本类型对象相加,比如两个时间类对象(由小时、分钟组成),可以在自定义时间类Time中添加两种形式表示相加的函数,分别为

1)Time add(const Time& t) const;

2)Time operator+(const Time& t) const;

mytime.h

#ifndef MYTIME_H
#define MYTIME_H

class Time {
private:
  int hours;
  int minutes;
public:
  Time();
  Time(int h, int m);
  void AddMin(int m);
  void AddHr(int h);
  void Reset(int h = 0, int m = 0);
  Time add(const Time& t) const;
  Time operator+(const Time& t) const;
  void Show() const;
};
#endif

mytime.cpp

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

Time::Time() {
  hours = 0;
  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::add(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 sum;
  sum.minutes = minutes + t.minutes;
  sum.hours = hours + t.hours + sum.minutes / 60;
  sum.minutes %= 60;
  return sum;
}

void Time::Show() const {
  std::cout << hours << " hours, " << minutes << " minutes" << std::endl;
}

usetime.cpp

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

using namespace std;

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

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

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

  total = coding.add(fixing1);
  cout << "After the first fixing, total time = ";
  total.Show();
  cout << endl;

  Time fixing2(1, 10);

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

  total = total.operator+(fixing2);
  cout << "After the second fixing, total time = ";
  total.Show();
  cout << endl;

  Time fixing3(3, 28);
  cout << "fixing3 time = ";
  fixing3.Show();
  cout << endl;
  total = total + fixing3;
  cout << "After the third fixing, total time = ";
  total.Show();
  cout << endl;

  return 0;
}

coding、fixing1、fixing2、fixing3均是Timg类的对象,两个Time对象相加有3种形式

1)total = coding.add(fixing1);

2)total = total.operator+(fixing2);

3)total = total + fixing3; 

显然,第3种方式使代码更加简洁,便于Time类的调用者使用()

3.通过友元实现运算符重载

实现运算符重载需要友元的原因:在为类重载二元运算符(带两个参数的运算符)有时需要友元,“实数乘以Time对象”就属于这种情况,重载的乘法运算符和重载的加法运算符的区别在于,重载的加法运算符结合两个Time对象,重载的乘法运算符将一个Time值与一个double值结合在一起,而这个区别限制了重载的乘法运算符的使用方式

Time A;
Time B;
A = B * 2.75;    // 左侧的操作数是调用对象
将会被转换为下面的函数调用
A = B.operator*(2.75);
但是,“A = 2.75 * B”无法调用B::operator*函数,因为2.75不是Time对象

可以在Time类中创建友元函数解决这个问题(2.75不是Time对象,所以无法创建Time类成员函数来解决这个问题,但是待创建的函数必须能够访问Time对象的成员变量,所以在此使用友元函数),在mytime.h中添加重载的乘法运算符的声明

Time operator*(double n) const;  // for A = B * 2.75
friend Time operator*(double n, const Time& t);  // for A = 2.75 * B

在mytime.cpp中添加重载的乘法运算符的定义

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

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

在上例中,两个重载的乘法运算符函数逻辑是相同的,所以在mytime.cpp省略“friend Time operator*(double n, const Time& t);”的定义,将mytime.h改为

Time operator*(double n) const;  // for A = B * 2.75
friend Time operator*(double n, const Time& t) {
  return t * n;
} // for A = 2.75 * B

4.重载<<运算符

可以对<<运算符重载,使之能与cout一起来显示对象的内容

在mytime.h中添加友元函数的声明

friend ostream& operator<<(ostream& os, const Time& t);

在mytime.cpp中添加友元函数的定义

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

注:新的Time类声明使operator<<()函数成为Time类的一个友元函数。但该函数不是ostream类的友元。operator<<()函数接受一个ostream参数和一个Time参数,因此表面看起来它必须同时是这两个类的友元。然而,尽管该函数访问了Time对象的各个成员,但只将ostream对象做为一个整体使用。因为operator<<()直接访问Time对象的私有成员,所以它必须是Time类的友元。但由于它并不直接访问ostream对象的私有成员,所以并不一定必须是ostream类的友元,所以不必修改ostream的定义

参考资料:

1.C++ Primer Plus(第6版)中文版

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值