c++ 运算符重载

运算符重载

运算符重载参考地址: https://www.cnblogs.com/xiaokang01/p/9166745.html

一、前言

    在平时的编码中,我们运用的运算符是内部构造好的一些标准运算符运算(比如加减乘除基本数值运算,逻辑运算符处理一些逻辑运算等),像对于两个对象数组相加或两个对象相加这些内部都是不支持的。C++里面有种操作叫函数重载,即采用相同的函数名和不同的特征标实现相同的基本操作。因此C++也将这个概念运用到运算符里面,使用相同的运算符和不同的特征标完成相同的基本操作(前提是:这里面至少有一个数据类型使用户自定义的)。
    C++里面内部本身也对一些运算符进行重载,*号运算符将其重载,将其运用于地址,<<左移运算符重载时起成为cout输出的一个标志。无疑,重载运算符的前提是这些运算符都是合法的,不能自己重定义一个运算符进行重载,这在C++里面是不被允许的。

重载运算符基础: 在这里函数名也可以称为运算符。
在这里插入图片描述

  代码示例:
调用的两种方法:
Time time1, time2, time3;
time3 = time1 + time2;
// 上述代码等同于
time3 = time1.operator+(time2);

在这里插入图片描述

注意: 引用不要返回局部变量或局部临时引用。函数执行完毕后,局部变量和临时引用会被释放,引用对象将指向不存在的数据。

以上的表达式还可以写成下面这样:

time4 = time1 + time2 + time3=time1.operator+(time2.operator+(time3)) //用于加法运算符是从右往左开始计算,所以是适用的。

二、重载的限制

不可重载限制:
1)重载运算符不必是成员函数,但必须有一个是用户自定义的,这主要是防止用户对标准类型进行重载。
以下是成员函数和非成员函数重载的区别
2)重载的类型得对应,不能将‘-’发符号重载为两个数之和。
3)重载时还不能修改运算符的优先级。
4)不能创建新的运算符,例如不能定义**operrator()函数来求幂。
5)不能重载以下的运算符:sizeof,’.’, ‘::’,’?’。

可重载的运算符和不可重载的运算符:
在这里插入图片描述

三、重载特征标不同操作数

例: Complex是一个对象,Complex = temp1, temp2。temp2 = temp1 * 3.45,在这里time1作为隐式调用可以采用成员函数实现;
例: temp2 = 3.45 * temp1;
上面例子,temp1用做显示调用,不能采用成员函数进行实现(按道理说也可以,但是你要去修改标准库里面符号重载,一般标准库是不建议去更改的),但可以采用全局函数实现,但成员变量a, b都是私有变量,除了公共的成员函数是没法访问的,所以采用全局函数重载时要把该函数声明为该类的友元函数。

#include <iostream>
using namespace std;

class Complax
{
private:
    int a;
    int b;
    // 重载友元函数 全局函数 操作符重载
    friend Complax operator+(Complax& c1, Complax& c2);
    friend Complax operator*(int num, Complax& c1);
public:
    Complax(int a = 0, int b = 0)
    {
        this->a = a;
        this->b = b;
    }
    void printC()
    {
        cout << "a = " << a << "\tb = " << b << endl;
    }
    // 2成员函数法 实现 - 运算符重载
    Complax operator-(Complax& c2)
    {
        //        this->a -= c2.a;
        //        this->b -= c2.b;
        //        return *this;  // 这一个会改变c1的值,因为是+=
        Complax temp(this->a - c2.a, this->b - c2.b);
        return temp;

    }

};
// 1全局函数法 实现 + 运算符重载
Complax operator+(Complax& c1, Complax& c2)
{
    Complax temp(c1.a + c2.a, c1.b + c2.b);
    return temp;
}

// 2不同特征标相加
Complax operator*(int num, Complax &c1) {
    return Complax(c1.a*num, c1.a*num);
}
// 2全局函数法 实现int和complex对象相加
/*
    全局函数,类成员函数方法实现运算符重载步骤
    1:要承认运算符重载是一个函数, 写出函数名称
    2: 根据操作数,写出函数参数
    3:根据业务,完善函数的返回值(看函数返回引用,元素,指针),及实现函数业务
*/
int main()
{
    Complax c1(1, 2), c2(3, 4);

    // 1全局函数法 实现 - 运算符重载
    // Complax operator+(Complax &c1, Complax &c2)
    Complax c3 = c1 + c2;
    c3.printC();

    // 2成员函数法 实现 - 运算符重载
    // Complax operator-(Complax &c2);
    Complax c4 = c1 - c2;
    c4.printC();

    Complax c5 = 5 * c2;
    c5.printC();

    return 0;
}

四、重载++,- -

    在C++里面我们都知道++和- -有前置++和后置++,前置++返回的是引用,后置++返回的是副本,- -也是一样的(前置++返回引用:在编译器中该操作就在原来分配的内存中进行操作。后置++返回副本:在编译器里面将数据进行复制一份到内存然后再操作)。

/ /特别注意 只有成员函数才有 this指针
// 1全局函数法 实现 前置++ 运算符重载
Complax& operator++(Complax &c1)
{
    c1.a++;
    c1.b++;
    return c1;
}
// 后置++
Complax operator++(Complax &c2, int) // int防止与前置++重载而加的占位符
{
    // 因为后置++是使用, 在让c2++所以要定义一个临时变量
    Complax tem = c2;
    c2.a++;
    c2.b++;
    return tem;
}

五、重载<<运算符

    以上complex是一个对象,前面我们将complex对象显示出来调用的是printC()成员函数进行打印。平时打印一些数值时调用cout << int(double)等就可以将数值输出到屏幕上。由于cout是ostream对象,ostream包含了对operator<<()定义,所以我们可以对<<进行如下重载。

//a)用全局函数方法实现 << 操作符
ostream& operator<<(ostream &out, Complex &c1)
{
    //out<<"12345,生活真是苦"<<endl;
    out<<c1.a<<" + "<<c1.b<<"i "<<endl;
    return out;
}

六、注意点

  1. 友员函数重载运算符常用于运算符的左右操作数类型不同的情况
  2. 在第一个参数需要隐式转换的情形下,使用友员函数重载运算符是正确的选择
  3. 友员函数没有 this 指针,所需操作数都必须在参数表显式声明,很容易实现类型的隐式转换
  4. C++中不能用友员函数重载的运算符有: = () [] ->
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值