C++ 运算符重载

一:运算符重载的方法

  • 形式:
    在这里插入图片描述

  • 对象 运算符 另一个值(可以不是对象,可以无)被解释为:对象.operator运算符(另一个值)
    在这里插入图片描述

  • 运算符被重载后,原来用于其他数据类型上的功能仍然被保留(重载),系统根据重载函数的规则匹配

  • 例:复数的相加
    在这里插入图片描述

二:运算符重载的规则:

  • 只能对已有运算符进行重载,不能定义新运算符

  • 不能重载的运算符只有五个:
    在这里插入图片描述

  • 不能改变操作对象的个数

  • 不能改变优先级

  • 不能改变结合性

  • 不允许带默认参数

  • 重载运算符的两侧至少有一个是类对象

  • =和&系统做了重载,=是对应内存拷贝,&是取地址

三:重载=运算符、重载构造函数实现含动态内存申请的赋值、复制

1.重载=的体外实现

class test{
  private:
    int a;
    int b;
    char *c;
  public:
    ...
    test &test::operator=(const test &t);  //重载=的声明
}

//重载=的体外实现
test &test::operator=(const test &t)
{
    a = t.a;
    b = t.b;
    delete[]c;  //释放原空间
    c = new char[strlen(t.c) + 1];  //申请新空间
    strcpy(c, t.c);
    return *this;  //返回对象自身
}

Q:返回类型test &,为什么不能是test?
A:t2 = t1 希望理解为 t2.opetator=(t1),即this指针指向t2,而=的语意希望执行后t2被改变,因此返回test &

另一个例子:complex operator+(complex &b);
c1 + c2 理解为 c1.operator(t2),+的语意不能改变c1,因此+应该返回临时对象,所以返回值是 complex 而不是 complex &

2.复制构造函数的体外实现:

test::test(const test &s)
{
    a = s.a;
    b = s.b;
    c = new char[strlen(s.c) + 1];  //申请新空间
    strcpy(c, s.c);
}

四:运算符重载作为类成员函数和友员函数

在这里插入图片描述

  • 因为要访问类的成员,所以需要定义为友员
  • 运算符的同一种重载实现,友员/成员只能选一个
  • 用全局普通函数也能实现运算符重载,但因为只能访问public对象,或通过类的公有成员函数访问private部分,因此效率低,一般不用

在这里插入图片描述

成员函数与友员函数的区别:

对单目运算符:

  • 成员函数是空参数
  • 友元函数是一个参数(必须是对象)

对双目运算符:

  • 成员函数是一个参数(可不是对象)
    对象(this) 双目运算符 参数
  • 友元函数是两个参数(一个必须是对象,另一个可不是)
    第一个参数 双目运算符 第二个参数
  • 对两个都是对象的情况:没区别
  • 对一个是对象的情况:在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 建议对单目运算符采用成员函数方式双目运算符采用友元函数方式
  • C++规定,某些运算符必须是成员函数形式(赋值=、下标[]、函数()),某些运算符必须是友元函数形式(流插入

五:例子

1.重载++

Complex& Complex::operator++()  //后缀
{
    real++;
    return this;
}

Complex Complex::operator++(int)  //后缀
{
    Complex c1(*this);  //复制构造函数,用对象自身初始化c1
    real++;
    return c1;
}

2.重载流插入/流提取运算符

在这里插入图片描述

istream& operator>>(istream &in, Complex &a)
{
    in >> a.real >> a.imag;
    return in;
}

ostream& operator<<(ostream &out, Complex &a)
{
    out << a.real;
    if (a.imag >= 0)
        out << '+';
    out << a.imag << 'i';
    return out;
}

六:不同类型数据间的转换

(一)用转换构造函数进行类型转换

在这里插入图片描述

  • 只能带一个参数,非该类的数据类型,将该参数转换为对应的对象
  • 系统无缺省定义,根据需要自行定义并使用

1.将double转换为Complex

class Complex{
  ...
  public
    ...
    Complex(double r) { real = r; imag = 0; }
    ...
}

在这里插入图片描述

2.整数n表示当天的秒,转换为Time对象

Time::Time(int n)
{
    hour = n / 3600;
    minute = n % 3600 / 60;
    sec = n % 60;
}

(二)用类型转换函数进行类型转换

在这里插入图片描述

  • 返回类型不是缺省的int,由类型名决定,无参数
  • 只能是成员函数形式
  • 在需要类型转换的地方被系统自动地隐式调用
Time::operator int()
{
    return hour * 3600 + minute * 60 + sec;
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值