运算符重载

运算符重载


1. 运算符重载

要重载运算符,需要使用被称为运算符函数的特殊函数形式。运算符的格式:

operatorop(argument-list)
operator+()    // 重载+运算符
operator*()    // 重载*运算符

运算符重载示例

计算时间:

// mytime0.h
#ifndef MYTIME0_H_
#define MYTIME0_H_

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;      // 常规的加法
	Time operator+(const Time & t) const;   // 重载加法运算符
	Time operator*(double n) const;         // 重载乘法法运算符
	void Show() const;
};
#endif
// mytime0.cpp
#include <iostream>
#include "mytime0.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类对象
// {
// 		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类对象
{
	Time sum;
	sum.minutes = minutes + t.minutes;
	sum.hours = hours + t.hours + sum.minutes / 60;
	sum.minutes %= 60;
	return sum;
} 

Time Time::operator*(double mult) const  // 返回一个Time类对象
{
	Time result;
	long totalminutes = hours * mult * 60 + minutes * mult;
	result.minutes = totalminutes % 60;
	result.hours = totalminutes / 60;
	return result;
} 

void Time::Show() const
{
	std::cout << hours << " hours, " << minutes << " minutes";
}
// usetime0.cpp
#include <iostream>
#include "mytime0.h"

int main()
{
	Time planning;
	Time coding(2, 40);
	Time fixing(5, 55);
	Time total;
	
	std::cout << "planning time = ";
	planning.Show();
	std::cout << std::endl;

	std::cout << "coding time = ";
	coding.Show();
	std::cout << std::endl;
	
	std::cout << "fixing time = ";
	fixing.Show();
	std::cout << std::endl;
	
	// total = coding.Sum(fixing);
	// std::cout << "coding.Sum(fixing) = ";
	// total.Show();
	// std::cout << std::endl;

	total = coding + fixing;
	std::cout << "coding + fixing = ";
	total.Show();
	std::cout << std::endl;

	return 0;
}

运行结果:

➜  C++ g++ main.cpp mytime0.cpp 
➜  C++ ./a.out                             
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
➜  C++ g++ main.cpp mytime0.cpp                                                 
➜  C++ ./a.out 
planning time = 0 hours, 0 minutes
coding time = 2 hours, 40 minutes
fixing time = 5 hours, 55 minutes
coding + fixing = 8 hours, 35 minutes

2. 运算符重载限制

  1. 重载后的运算符必须至少有一个操作数是用户定义的类型,这将防止用户为标准类型重载运算符;
  2. 使用运算符时不能违反运算符原来的句法规则,同样不能修改运算符的优先级;
  3. 不能创建新的运算符。例如,不能定义operator**()函数来表示求幂。
  4. 大多数运算符都可以通过成员函数或非成员函数进行重载,但下面的运算符只能通过成员函数进行重载:
    • =: 赋值运算符、
    • (): 函数调用运算符
    • [ ]: 下标运算符
    • ->: 通过指针访问类成员的运算符。

3. 运算符操作数问题

在前面的Time类示例中,重载的乘法运算符与其他两种运算符的差别在于,它使用了两种不同的类型。也就是说,加法运算符都结合了两个Time值,而乘法运算符将一个Time值与一个double值结合在一起。这就限制了该运算符的使用方式。需要记住,左侧的操作数是调用对象。也就是说,下面的语句:

A = B * 2 将被转换为下面的成员函数调用:
A = B.operator*(2);

这就使得A = 2 * B的方式编写程序会报错,这是因为2不是Time类型对象,编译器不能调用成员函数来替换这个表达式。

解决上述问题的方法可以是构造非成员函数来重载运算符,这样编译器能够将A = 2 * B的表达式与下面的非成员函数匹配:

A = operator*(2, B);
Time operator*(double m, const Time & t); // 函数原型

使用非成员函数会引发一个问题:非成员函数不能直接访问类的私有数据,至少常规函数不可以。这就需要我们定义一种特殊的非成员函数可以访问类的私有成员,也即友元函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值