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

 更新时间:2025年05月22日 11:03:52   作者:zzh_zao  
这篇文章主要介绍了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++ 不允许创建新的运算符,只能重载已有的运算符。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C++中的自增与自减

    C++中的自增与自减

    这篇文章主要介绍了C++中的自增与自减,自增与自减是C++当中两个使用频率非常高的运算符,不仅在循环当中用到,在日常的代码当中也经常使用,下面来看看文章得具体介绍
    2021-11-11
  • C语言的合法标识符与整型详解

    C语言的合法标识符与整型详解

    这篇文章主要为大家详细介绍了C语言的合法标识符与整,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • C/C++语言printf命令使用方法

    C/C++语言printf命令使用方法

    在本篇文章里小编给大家分享了关于C/C++语言printf命令使用方法和步骤,对此有需要的朋友们学习下。
    2019-01-01
  • C/C++计算程序执行时间的几种方法实现

    C/C++计算程序执行时间的几种方法实现

    本文主要介绍了C/C++计算程序执行时间的几种方法实现,包括使用clock()函数、使用库和使用time.h头文件中的time()函数,具有一定的参考价值,感兴趣的可以了解一下
    2025-02-02
  • 详解c++20协程如何使用

    详解c++20协程如何使用

    这篇文章主要介绍了详解c++20协程如何使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • C++有限状态机实现计算器小程序

    C++有限状态机实现计算器小程序

    这篇文章主要为大家详细介绍了C++有限状态机实现计算器小程序的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • C语言static修饰函数详细解析

    C语言static修饰函数详细解析

    以下是对C语言中的static修饰函数进行了详细的分析介绍,需要的朋友可以过来参考下
    2013-08-08
  • C++手撸智能指针的教程分享

    C++手撸智能指针的教程分享

    在前文中小编为大家介绍了C++智能指针的一些使用方法和基本原理,所以本文就来自己动手,从0到1实现一下自己的unique_ptr和shared_ptr吧
    2023-05-05
  • C语言 单向链表的增删查改快速掌握

    C语言 单向链表的增删查改快速掌握

    单向链表特点是链表的链接方向是单向的,访问要通过顺序读取从头部开始。链表是使用指针构造的列表,是由一个个结点组装起来的,又称为结点列表。其中每个结点都有指针成员变量指向列表中的下一个结点,head指针指向第一个结点称为表头,而终止于最后一个指向nuLL的指针
    2021-11-11
  • C语言教程之数组详解

    C语言教程之数组详解

    这篇文章主要为大家介绍了C语言教程之数组,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01

最新评论