【C++笔记】《C++ Primer Plus》学习笔记——操作符重载(一)

《C++ Primer Plus》学习笔记——操作符重载(一)


操作符重载简介

C++允许将操作符重载扩展到用户定义的类型,例如,允许使用+实现两个对象“相加”。
举例:两个数组的相加通常需要以下的for循环语句来实现:

for(int i = 0; i < 10; i ++)
    sum[i] = a[i] + b[i];  //逐个逐个元素相加

如果定义一个表示数组的类,并重载了+操作符,便可以直接用以下语句来实现两个数组相加的功能:

sum = a + b;   //重载操作符+后,两个对象直接相加


操作符函数格式

operator op(argument-list)


引例:常规方法实现Time类相加

Time类包含两个int类型的成员变量:hours和minutes。
两个Time对象相加,当分钟位的总和超过59时,必须向小时位进一位。例如1h30min + 1h45min = 3h15min。

Time类中使用Sum()函数实现时间相加操作。以下为Time类的成员函数Sum()的原型声明:

Time Sum(const Time & t) const;

Sum()函数中,调用对象为被加数,参数中的对象为加数,返回值为一个Time对象,该对象保存了两对象之和。
通过整除和模除来调整hours和minutes的值,实现两个Time对象的相加运算。
注意:这里的参数声明为引用,目的是为了提高效率。按值传递Time对象,代码功能相同,但传递引用会使速度更快、使用的内存更少。

以下为完整的Time类声明及定义代码。

Time类头文件如下:

//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;  
    void Show() const; 
};

Time类实现文件:

//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; 
} 

 //Sum()函数通过整除和模除来调整hours和minutes的值 
 //调用对象为被加数,参数对象为加数,返回值为两对象之和 
Time Time::Sum(const Time &t) const{  
    Time sum; 
    sum.minutes += minutes + t.minutes; 
    sum.hours += sum.minutes/60 + hours + t.hours; 
    sum.minutes %= 60; 
    return sum; 
} 

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

Time类测试代码如下:

//main.cpp

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

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

输出结果如下:

planing time = 0hours, 0minutes 
coding time = 2hours, 40minutes 
fixing time = 5hours, 55minutes 
total time = 8hours, 35minutes


例1:添加加法操作符实现Time类相加

要在Time类中重载加法操作符,只需将Sum()的名称改为operator+()即可。
将Time类的Sum()修改成operator+():

//mytime1.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 operator+ (const Time & t) const;  //修改后
    void Show() const;
};
//mytime1.cpp
#include<iostream>
#include "mytime1.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 += sum.minutes/60 + hours + t.hours;
    sum.minutes %= 60;
    return sum;
}

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

函数operator+()和Sum()一样,由一个Time对象调用,将第二个Time对象作为参数,最后返回一个Time对象。
因此,可以像调用Sum()一样调用operator+()函数:

total = coding.operator+ (fixing);   //法一:函数表示法

使用操作符重载后,我们还能使用一种更为简便和直观的操作符表示法:

total = coding + fixing;    //法二:操作符表示法

注意:在操作符表示法中,操作符左侧的对象是调用对象,操作符右边的对象是作为参数被传递的对象。
上述两种表示法是等价的,都将调用operator+()方法,测试代码如下:

//main.cpp

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

int main(){
    using std::cout;
    using std::endl;
    Time planning;
    Time coding(2, 40);
    Time fixing(5, 55);
    Time total;

    cout<<"planing time = ";
    planning.Show();
    cout<<endl;

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

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

    total = coding + fixing;   //操作符表示法
    //total = coding.operator+(fixing); //函数表示法
    cout<<"coding + fixing = ";
    total.Show();
    cout<<endl;

    Time morefixing(3,28);
    cout<<"more fixing time = ";
    morefixing.Show();
    cout<<endl;

    total = morefixing.operator+(total);
    cout<<"morefixing.operator+(total) = ";
    total.Show();
    cout<<endl;

    return 0;
}

输出结果如下:

planing time = 0hours, 0minutes
coding time = 2hours, 40minutes
fixing time = 5hours, 55minutes
coding + fixing = 8hours, 35minutes
more fixing time = 3hours, 28minutes
morefixing.operator+(total) = 12hours, 3minutes

此外,重载加法运算符后,将两个以上的对象相加仍然是合法的,如:

t4 = t1 + t2 + t3;

上述操作等价于以下函数调用:

t4 = t1.operator+(t2.operator+(t3));


例2:其他重载操作符

除了加法操作符,还有一些其他的操作符对Time类来说是有意义的。
下面为Time类重载减法和乘法操作符,实现两个时间相减和时间乘以一个因子的操作。
同理,需要创建两个函数:
operator-()和operator*()。

新的头文件如下:

//mytime2.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 operator+(const Time & t) const;  
    Time operator-(const Time & t) const;    //重载减法操作符
    Time operator*(double n) const;    //重载乘法操作符
    void Show() const;
};

将新增的方法添加到实现文件中:

//mytime2.cpp

#include<iostream>
#include "mytime2.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 += sum.minutes/60 + hours + t.hours;
    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 n) const{
    Time result;
    long totalminutes = (hours * 60 + minutes) * n;
    result.hours = totalminutes / 60;
    result.minutes = totalminutes % 60;
    return result;
}

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

测试代码:

//main.cpp

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

int main(){
    using std::cout;
    using std::endl;
    Time planning;
    Time coding(4, 35);
    Time fixing(2, 47);
    Time total;

    cout<<"planing time = ";
    planning.Show();
    cout<<endl;

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

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

    total = coding + fixing;    //操作法表示法:加法
    cout<<"total time = ";
    total.Show();
    cout<<endl;

    total = total * 1.5;     //操作法表示法:乘法
    cout<<"total * 1.5 = ";   
    total.Show();
    cout<<endl;

    total = coding - fixing;    //操作符表示法:减法
    cout<<"tcoding - fixing = ";
    total.Show();
    cout<<endl;

    return 0;
}

输出结果如下:

planing time = 0hours, 0minutes
coding time = 4hours, 35minutes
fixing time = 2hours, 47minutes
total time = 7hours, 22minutes
total * 1.5 = 11hours, 3minutes
tcoding - fixing = 1hours, 48minutes
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值