当前位置: 代码网 > it编程>编程语言>C/C++ > C++类和对象之运算符重载解读

C++类和对象之运算符重载解读

2025年05月22日 C/C++ 我要评论
c++ 运算符重载一、什么是运算符重载?运算符重载是 c++ 的一种特性,它允许程序员为自定义类型(如类和结构体)重新定义运算符的行为。通过运算符重载,我们可以使用熟悉的运算符语法来操作自定义类型的对

c++ 运算符重载

一、什么是运算符重载?

运算符重载是 c++ 的一种特性,它允许程序员为自定义类型(如类和结构体)重新定义运算符的行为。通过运算符重载,我们可以使用熟悉的运算符语法来操作自定义类型的对象,从而使代码更加简洁、直观。

当运算符被⽤于类类型的对象时,c++语⾔允许我们通过运算符重载的形式指定新的含义。c++规定类类型对象使⽤运算符时,必须转换成调⽤对应运算符重载,若没有对应的运算符重载,则会编译报错。

例如,我们可以为自定义的复数类重载 + 运算符,使得两个复数对象可以直接使用 + 进行相加:

complex a(1, 2);
complex b(3, 4);
complex c = a + b; // 使用重载的 + 运算符

二、运算符重载的语法规则

在 c++ 中,运算符重载通过定义特殊的成员函数或非成员函数来实现。

其基本语法如下:

返回类型 operator运算符(参数列表) {
    // 函数体
}

其中:

  • operator 是 c++ 的关键字,用于声明一个运算符重载函数。
  • 运算符 是要重载的运算符,如 +, -, *, / 等。
  • 返回类型 是运算符重载函数的返回值类型,通常与操作数的类型相关。
  • 参数列表 是运算符重载函数的参数,参数的个数和类型取决于运算符的种类和重载方式。

注意:

  • ⼀个类需要重载哪些运算符,是看哪些运算符重载后有意义
  • 重载++运算符时,有前置++和后置++,运算符重载函数名都是operator++,⽆法很好的区分。c++规定,后置++重载时,增加⼀个int形参,跟前置++构成函数重载,⽅便区分。
  • 当运算符被⽤于类类型的对象时,c++语⾔允许我们通过运算符重载的形式指定新的含义。c++规定类类型对象使⽤运算符时,必须转换成调⽤对应运算符重载,若没有对应的运算符重载,则会编译报错。
  • 运算符重载是具有特殊名字的函数,他的名字是由operator和后⾯要定义的运算符共同构成。和其他函数⼀样,它也具有其返回类型和参数列表以及函数体。
  • 重载运算符函数的参数个数和该运算符作⽤的运算对象数量⼀样多。⼀元运算符有⼀个参数,⼆元运算符有两个参数,⼆元运算符的左侧运算对象传给第⼀个参数,右侧运算对象传给第⼆个参数。
  • 如果⼀个重载运算符函数是成员函数,则它的第⼀个运算对象默认传给隐式的this指针,因此运算符重载作为成员函数时,参数⽐运算对象少⼀个。
  • 运算符重载以后,其优先级和结合性与对应的内置类型运算符保持⼀致。
  • 不能通过连接语法中没有的符号来创建新的操作符:⽐如operator@。

重载<<和>>时,需要重载为全局函数,因为重载为成员函数,this指针默认抢占了第⼀个形参位置,第⼀个形参位置是左侧运算对象,调⽤时就变成了 对象<<cout,不符合使⽤习惯和可读性。

重载为全局函数把ostream/istream放到第⼀个形参位置就可以了,第⼆个形参位置当类类型对象。

成员函数重载

运算符重载函数可以作为类的成员函数来定义。在这种情况下,函数的参数个数比运算符的操作数少一个,因为第一个操作数是通过 this 指针隐式传递的。

非成员函数重载

运算符重载函数也可以作为非成员函数(全局函数或友元函数)来定义。

在这种情况下,函数的参数个数与运算符的操作数相同。

赋值运算符重载

赋值运算符重载是⼀个默认成员函数,⽤于完成两个已经存在的对象直接的拷⻉赋值,这⾥要注意跟拷⻉构造区分,拷⻉构造⽤于⼀个对象拷⻉初始化给另⼀个要创建的对象。

赋值运算符重载的特点:

  • 赋值运算符重载是⼀个运算符重载,规定必须重载为成员函数。赋值运算重载的参数建议写成const当前类类型引⽤,否则会传值传参会有拷⻉
  • 有返回值,且建议写成当前类类型引⽤,引⽤返回可以提⾼效率,有返回值⽬的是为了⽀持连续赋值场景。
  • 没有显式实现时,编译器会⾃动⽣成⼀个默认赋值运算符重载,默认赋值运算符重载⾏为跟默认拷⻉构造函数类似,对内置类型成员变量会完成值拷⻉/浅拷⻉(⼀个字节⼀个字节的拷⻉),对⾃定义类型成员变量会调⽤他的赋值重载函数。

拷贝构造:一个存在的对象去初始化另一个要实例化的对象; 赋值重载:已存在的两个对象之间的拷贝,注意返回值为类类型,处理连续赋值的情况

取地址运算符重载

const成员函数

  • 将const修饰的成员函数称之为const成员函数,const修饰成员函数放到成员函数参数列表的后⾯。
  • const实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进⾏修改。date* const this 变为 const date* const this

取地址运算符重载

  • 取地址运算符重载分为普通取地址运算符重载和const取地址运算符重载,⼀般这两个函数编译器⾃动⽣成的就可以够我们⽤了,不需要去显⽰实现。
  • 除⾮⼀些很特殊的场景,⽐如我们不想让别⼈取到当前类对象的地址,就可以⾃⼰实现⼀份,胡乱返回⼀个地址。

三、可重载的运算符和不可重载的运算符

可重载的运算符

c++ 中大部分运算符都可以被重载,包括:

  • 算术运算符:+, -, *, /, %, ++, --
  • 比较运算符:==, !=, <, >, <=, >=
  • 逻辑运算符:&&, ||, !
  • 位运算符:&, |, ^, ~, <<, >>
  • 赋值运算符:=, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
  • 其他运算符:[], (), ->, ,, *(解引用), &(取地址)

不可重载的运算符

c++ 中少数运算符不能被重载,包括:

  • 作用域解析运算符:::
  • 成员访问运算符:..*
  • 条件运算符:?:
  • 类型转换运算符:typeiddynamic_cast
  • 编译时运算符:sizeof

五、运算符重载的注意事项

在使用运算符重载时,需要注意以下几点:

  • 遵循运算符的原有语义:运算符重载应该保持运算符原有的语义,避免造成混淆。例如,重载 + 运算符应该实现加法的语义,而不是减法。
  • 不要滥用运算符重载:虽然运算符重载可以使代码更加简洁,但过度使用或滥用会使代码变得难以理解和维护。
  • 保持运算符的优先级和结合性:运算符重载不能改变运算符的优先级和结合性,这是由语言规定的。
  • 正确处理 const 对象:如果运算符重载函数不修改对象的状态,应该将其声明为 const 成员函数。
  • 注意内存管理:在重载赋值运算符和拷贝构造函数时,需要特别注意深拷贝和浅拷贝的问题,避免内存泄漏。
  • 避免创建新的运算符:c++ 不允许创建新的运算符,只能重载已有的运算符。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com