C++:运算符重载

C++:运算符重载

标签(空格分隔): c++
作者:陈小默


当我们学习C++的时候,一定接触过cout对象,你一定好奇过为什么左移运算符在这里就成了插入运算符了呢?所以这一节我们就来介绍一下吊炸天的C++运算符重载机制。

运算符重载规则

operatorOP(argument-list)

重载运算符使用了被称作运算符函数的特殊函数形式。其中OP代表有效的C++运算符,也就是说只能使用C++中已有的运算符,因为重载的意思就是给已有的运算符赋予新的意义。像C++并不存在@运算符,理所当然我们也就不能重载@了。

自定义时间运算

这里我们定义一个表示时间的类,时间的内部实现是一个long long类型的数据。
我们需要这个时间类能具有设置和显示两个功能。并且还能自定义运算符,下面为time.h头文件内容

#ifndef primer_time_h
#define primer_time_h
#include<string>
class Time{
private:
    enum {SECOND=1000,MINUTE=60*1000,HOURS=60*60*1000};
    long long time;
public:
    void setMinutes(int m);
    void setHours(int h);
    void setSecondes(int s);
    long long getLongTime();
    Time operator+(Time t);
    Time operator-(Time t);
    Time operator*(int n);
    Time operator/(int n);
    void toString();
};

#endif

在声明中,我们定义了秒、分钟、小时的单位毫秒数常量。还有一个用来存储时间的long long类型的time。下面的toString方法用来打印时间,另外我们还重载了时间的加减乘除四个运算符。
下面看具体实现

#include "stdafx.h"
#include "time.h"

void Time::setHours(int h){
    if(h>=0)time = time%HOURS+h*HOURS;
}
void Time::setMinutes(int m){
    if(m>=0&&m<60)time = (time-time%HOURS)+time%MINUTE+m*MINUTE;
}
void Time::setSecondes(int s){
    if (s>=0&&s<60)time = (time-time%MINUTE)+s*SECOND;
}
long long Time::getLongTime(){
    return time;
}
void Time::toString(){
    int hours = int(time/HOURS);
    int minutes = int((time%HOURS)/MINUTE);
    int seconds = int(time%MINUTE/SECOND);
    cout<<"Time["<<hours<<":"<<minutes<<":"<<seconds<<"]"<<endl;
}
Time Time::operator+(Time t){
    time+=t.getLongTime();
    return *this;
}
Time Time::operator-(Time t){
    time-=t.getLongTime();
    return *this;
}
Time Time::operator*(int n){
    time*=n;
    return *this;
}
Time Time::operator/(int n){
    time/=n;
    return *this;
}

重载运算符的两种使用方式

第一种,函数调用形式

time3 = time1.operator+(time2);

第二种,就是我们想要的运算符表示法

time = time1 + time2;

多个重载运算符的连续运算

如果我们将表达式写成如下这种形式,能不能正常运行呢?

time = time1 + time2 + time3;

想要回答这个问题,就要看这个表达式如何被转换为函数调用形式。在C++语法规则中+是自左向右结合的运算符。所以上述语句会被转化为如下形式

time = time1.operator+(time2 + time3);

而括号内又可以转换,于是得到最终结果

time = time1.operator+(time2.operator+(time3));

重载限制

1,重载后的操作符必须有一个操作数是用户类型,因为如果我们随意更改基本类型的操作符,那么程序将变得无法阅读。比如用户在声明中定义了如下方法

double double::operator+(double d){
    return *this-d;
}

那么我们在程序中看到的3.0+1.0的结果又是什么呢?
2,使用运算符时不能违反原有的句法规则。例如,不能将一个运算符重载为操作数。

int x;
% x;//invalid

3,不能创建新的运算符,只能使用已有的运算符。
4,不能重载以下运算符

符号含义
sizeof占用空间运算符
.成员运算符
.*成员指针运算符
::作用域解析符
?:三元条件运算符
typeidRTTI运算符
const_cast强制类型转换运算符
dynamic_cast强制类型转换运算符
reinterpret_cast强制类型转换运算符
static_cast强制类型转换运算符

5,以下表中的运算符可以被重载

+-*/%^&|~=
!=<>+=-+*=/=%=
^=&=|=<<>>>>=<<===!=
<=>=&&||++,->*->
()[]newdeletenew[]delete[]

6,上表中的下列运算符只能通过成员函数重载,其他的可以通过成员或者非成员函数进行重载

符号含义
=赋值运算符
()函数调用运算符
[]下标运算符
->指针成员访问运算符
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值