C++程序设计——五

实验目的

学习并掌握C++运算符重载相关的内容

实验内容

运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
在C++中,我们可以重载大部分内置的运算符
运算符。
重载有两种方式,一种是类内重载(运算符重载为类的成员函数),一种是类外重载(运算符重载为类的友元函数)。
这里我们先介绍类内重载

最简单的函数重载

在进行运算符重载前,我们先来一个最简单的函数重载。
在这里插入图片描述

类内重载

普通运算符:±*/

下面为源代码

#include <iostream>
using namespace std;

class num
{
public:
    num operator+(num& y)
    {
        num temp;
        temp.lenth=this->lenth+y.lenth;
        temp.width=this->width+y.width;
        return temp;
    }
    num operator-(num& y)
    {
        num temp;
        temp.lenth=this->lenth-y.lenth;
        temp.width=this->width-y.width;
        return temp;
    }
    num operator*(num& y)
    {
        num temp;
        temp.lenth=this->lenth*y.lenth;
        temp.width=this->width*y.width;
        return temp;
    }
    num operator/(num& y)
    {
        num temp;
        temp.lenth=this->lenth/y.lenth;
        temp.width=this->width/y.width;
        return temp;
    }

    int lenth;
    int width;
};
int main()
{
    num x,y;
    x.lenth=31;
    x.width=4;
    y.lenth=62;
    y.width=8;
    num z=x+y;
    cout<<"重载后,两者相加"<<endl;
    cout<<z.lenth<<endl;
    cout<<z.width<<endl;
    z=x-y;
    cout<<endl;
    cout<<"重载后,两者相减"<<endl;
    cout<<z.lenth<<endl;
    cout<<z.width<<endl;
    z=x*y;
    cout<<endl;
    cout<<"重载后,两者相乘"<<endl;
    cout<<z.lenth<<endl;
    cout<<z.width<<endl;
    z=x/y;
    cout<<endl;
    cout<<"重载后,两者相除"<<endl;
    cout<<z.lenth<<endl;
    cout<<z.width<<endl;
}

运行结果
在这里插入图片描述
先看类num的定义,我们定义每个num对象都有两个int类型的属性,lenth和width;然后重载运算符:+、-、*、/。

对于operator+:直接把两个num对象的两个属性分别相加,得到新的num对象,其中x.length=31,y.lenth=62,相加得到z.lenth=93;
对于operator-:直接把两个num对象的两个属性分别相减,得到新的num对象,其中x.length=31,y.lenth=62,相减得到z.lenth=-31;
对于operator*:直接把两个num对象的两个属性分别相乘,得到新的num对象,其中x.length=31,y.lenth=62,相乘得到z.lenth=1922;
对于operator/:直接把两个num对象的两个属性分别相除,得到新的num对象,其中x.length=31,y.lenth=62,相除取整得到z.lenth=0;

疑问:为什么重载运算符的形参要用引用?一定要用引用吗?

在代码中,要注意的是,重载运算符时,形式参数使用了引用。其实引用不是必须要用的,但使用引用可以大大减少对象拷贝的开销;在我的理解中,重载运算符时一般不会改变形参的值,所以为了减少构造开销可以使用引用,这是很常见的一个技巧,而且,若是担心实参因此被改变,也可以在形参前添加const关键字,如下:

num operator+(const num& y){}

”=”运算符重载

源代码修改添加如下:

num& operator=(const num& y)
   {
       cout<<"使用了重载后的=运算符"<<endl;
       this->width=y.width;
       this->lenth=y.lenth;
       return *this;
   }

   int lenth;
   int width;
};
int main()
{
   num x,y;
   x.lenth=31;
   x.width=4;
   y.lenth=62;
   y.width=8;
   num z;
   z=x=y;
   cout<<"重载=运算符后的x"<<endl;
   cout<<x.lenth<<endl;
   cout<<x.width<<endl;
   cout<<endl;
   cout<<"重载=运算符后的y"<<endl;
   cout<<y.lenth<<endl;
   cout<<y.width<<endl;
   cout<<endl;
   cout<<"重载=运算符后的z"<<endl;
   cout<<z.lenth<<endl;
cout<<z.width<<endl;
}

相对上次的代码,只更新了函数
num& operator=(const num& y)和main函数。
结果如下:
在这里插入图片描述
我们发现,它调用了两次我们重载后的”=”运算符,而且这个计算结果是x和y、z相等,都等于之前y的值,这说明实现计算x=y,再计算z=x;

然后我们若是更改代码,将

num z;
z=x=y;

更改为

num z=x;
cout<<"------------------------"<<endl;
x=y;

结果变为
在这里插入图片描述
这说明在构造新对象时用=运算符,它还是会调用原来的而不是我们重载后的=运算符。

问题 为什么重载=运算符,它的返回类型需要使用引用?

因为这样可以减少拷贝构造的时间耗费,此外就是这样可以实现连续赋值。
我们再次来改变代码,得到

num z;
(z=x)=y;

在使用引用的情况下,结果如下:
在这里插入图片描述
这个结果说明,先计算z=x,再计算z=y,实现了连续赋值;
但返回值若不使用引用,结果如下
在这里插入图片描述
这说明在计算完z=x后就没有成功的再次将y的值赋给z。
因为如果返回的类型是值,不是引用,那么在计算z=x时,执行重载的=运算符,返回的是一个匿名对象,它是一个右值,这个临时右值不能成功执行=z,因为右值不能当左值使用,而引用既可以作右值,也可以作左值。

实验结论

运算符重载可以帮助我们让运算符之前不能完成的任务完成,但是重载一定要考虑清楚使用情况和条件,避免出现错误,而且,非必要重载!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值