当前位置: 首页 > news >正文

c++——运算符的重载

目录

一、 运算符重载基本语法和规则

1.运算符重载的定义

2.运算符重载的基本语法

3.运算符的重载规则

二、成员函数的重载和非成员函数的重载

1.成员函数重载

2.非成员函数的重载

三、具体运算符的重载

1.重载+

(1)引入——实现复数类的Add函数

(2)使用operator实现+重载

2.重载-

3.重载=

(1)注意

(2)实现要点

(3)对比值返回和引用返回

4.重载前置++

5.重载后置++

6.重载<

四、常见运算符的const总结

一、 运算符重载基本语法和规则

1.运算符重载的定义

允许用户为自定义类型重新定义运算符的行为,使得对象可以像内置类型一样进行运算。

2.运算符重载的基本语法

返回类型 operator运算符(参数列表) {// 实现逻辑
}

3.运算符的重载规则

①不能创造新运算符:只能重载已有的运算符(如 +==[]()......

注意:只有极少部分运算符不可以被重载,比如:三目运算符、成员操作符、作用域操作符、sizeof操作符、typeid类型信息运算符。

②至少有一个操作数是自定义类型:不能为内置类型重载运算符。

③保持运算符原有语义:避免滥用(如用 + 实现减法)。

二、成员函数的重载和非成员函数的重载

1.成员函数重载

左侧操作数:隐式绑定到 this 对象。

参数数量:比运算符的操作数少一个(如二元运算符只需一个参数)。

2.非成员函数的重载

所有操作数:显式声明为参数。

常用场景:左侧操作数不是当前类(如 operator<<)或需要隐式类型转换。

注意:非成员函数重载若需要访问私有成员,需声明为友元。

三、具体运算符的重载

1.重载+

(1)引入——实现复数类的Add函数

判断以下5种方法的正确性:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Complex
{
private:double Real, Image;
public:Complex(double r = 0.0, double i = 0.0) :Real(r), Image(i) //构造函数 {cout << "Create object: " << this << endl;}Complex(const Complex& com) :Real(com.Real), Image(com.Image)//拷贝构造函数{cout << "Copy Create object: " << this << endl;}~Complex()  //析构函数{cout << " Destory Object:" << this << endl;}void print() const  // 普通方法和常方法都可以调用{cout << "Real=" << Real << 't' << "Image=" << Image << endl;}/*第一种写法,传递的参数是副本(调用拷贝构造函数创建实参的副本),需要创建额外的空间,支持常量对象*/Complex Add(Complex cx)  {return Complex(this->Real + cx.Real, this->Image + cx.Image);}/*第二种写法,传递的参数是引用,不需要拷贝实参的副本,函数效率更高,不支持常量的对象*//*Complex Add(Complex& cx)  {return Complex(this->Real + cx.Real, this->Image + cx.Image);}*//*第三种写法,传递的参数是常引用,表示被引用的实参是不可改变的,不支持常量对象*/Complex Add(const Complex& cx){return Complex(this->Real + cx.Real, this->Image + cx.Image);}//第四种写法,普通方法和常方法都可以调用,比较适用Complex Add(const Complex& cx) const //常成员函数{return Complex(this->Real + cx.Real, this->Image + cx.Image);}/*第五种写法,错误注意:不能返回一个临时对象的引用。因为函数执行完毕后,临时对象就会被销毁,此时引用指向的是一个已经不存在的对象。*/Complex& Add(const Complex& cx) const{return Complex(this->Real + cx.Real, this->Image + cx.Image);}
};
int main()
{const Complex ca(1, 2), cb(3, 4); //常对象,不允许修改对象的值Complex cc;cc = ca.Add(cb);   //等价于//cc = Add(&ca, cb);return 0;
}

解释上述5种方法:

1.Complex Add(Complex cx)  ——值传递,但需要拷贝实参的副本,效率低下。(√)

2.Complex Add(Complex& cx)  ——引用传递,不需要拷贝的实参的副本,函数效率更高,但不能接受常量对象作为参数(但不能被常对象调用)    (×)

3.Complex Add(const Complex& cx)——常引用传递,不允许修改实参的值,也不能被常对象调用。(×)

4. Complex Add(const Complex& cx) const ——常引用+常方法(普通方法和常方法都可以调用)(√)

5.Complex& Add(const Complex& cx) const——返回临时对象的引用。 (×)

注意:不能返回一个临时对象的引用。因为函数执行完毕后,临时对象就会被销毁,此时引用指向的是一个已经不存在的对象。

总结:一般使用引用作为函数参数,可以避免拷贝,但要注意不要返回临时变脸的引用。

(2)使用operator实现+重载

①常对象与常对象相加

//运算符的重载
class Complex
{
private:double Real, Image;
public:Complex(double r = 0.0, double i = 0.0) :Real(r), Image(i) //构造函数 {cout << "Create object: " << this << endl;}Complex(const Complex& com) :Real(com.Real), Image(com.Image)//拷贝构造函数{cout << "Copy Create object: " << this << endl;}~Complex()  //析构函数{cout << " Destory Object:" << this << endl;}void print() const  // 普通方法和常方法都可以调用{cout << "Real=" << Real << 't' << "Image=" << Image << endl;}//使用Add实现常对象的方法Complex Add(const Complex& cx) const //常成员函数{return Complex(this->Real + cx.Real, this->Image + cx.Image);}//重载+  Complex operator+(const Complex &cx) const{return Complex(this->Real + cx.Real, this->Image + cx.Image);}};
int main()
{const Complex ca(1, 2), cb(3, 4); //常对象,不允许修改对象的值Complex cc;cc = ca.Add(cb);   //等价于//cc = Add(&ca, cb);return 0;
}

2.重载-

与重载+原理一样(*、/ 原理也相同)

3.重载=

(1)注意

如果在类的定义中没有显式给出赋值运算符重载函数时,系统会自动调用缺省的赋值函数。

(2)实现要点

①返回引用:为了支持连续赋值(例如a = b = c),赋值运算符应返回*this的引用。

②检查自赋值:在进行赋值操作之前,要先检查thisother是否为同一个对象,避免不必要的操作甚至错误。

(3)对比值返回和引用返回

重载=

1.为什么采用引用返回,不采用值返回?
原因:赋值操作要支持连续赋值,支持链式调用,避免值拷贝造成的大量开销。

2.避免将赋值重载函数设计为常方法

常方法会限制this,使其内容不被修改。而赋值操作,需要修改值。

4.重载前置++

前置++返回自增后的引用,支持链式操作,不创建临时对象,效率高。

5.重载后置++

后置++返回自增前的拷贝,存在拷贝构造和析构的开销,效率低。

6.重载<

主要用于运算符的比较,返回一个布尔值。

7.重载类型强转运算符

将一个类型的值转换为另一个类型。

四、常见运算符的const总结

(1)不修改对象状态:声明为 const,允许对常量对象使用。

(2)修改对象状态:不能声明为 const

(3)返回当前对象引用:若修改对象(如 +=),不声明为 const;若不修改,声明为 const

如图所示:

运算符类型是否需要 const示例代码
比较运算符(==✅ 必须bool operator==(const T&) const
算术运算符(+✅ 推荐T operator+(const T&) const
赋值运算符(=❌ 不能T& operator=(const T&)
复合赋值(+=❌ 不能T& operator+=(const T&)
前置自增(++a❌ 不能T& operator++()
后置自增(a++❌ 通常不T operator++(int)
类型转换(double✅ 必须operator double() const
下标运算符([]取决于是否修改T& operator[](int)(非 const 版本)

http://www.dtcms.com/a/275001.html

相关文章:

  • 鸿蒙开发之ArkTS常量与变量的命名规则
  • 面向对象编程
  • [面试] 手写题-选择排序
  • 持有对象-泛型和类型安全的容器
  • 深度学习中的归一化技术详解:BN、LN、IN、GN
  • Kubernetes 高级调度特性
  • C语言:位运算
  • Redis 哨兵机制
  • 多代理系统(multi-agent)框架深度解析:架构、特性与未来
  • 无代码自动化测试工具
  • STM32G473串口通信-USART/UART配置和清除串口寄存器状态的注意事项
  • 隆重介绍 Xget for Chrome:您的终极下载加速器
  • 开源界迎来重磅核弹!月之暗面开源了自家最新模型 K2
  • 从延迟测试误区谈起:SmartPlayer为何更注重真实可控的低延迟?
  • gitee 代码仓库面试实际操作题
  • Cadence Virtuoso中如何集成Calibre
  • Java进阶---并发编程
  • 打造未来制造核心力:虚拟调试的价值与落地思路
  • YOLO-DETR如何提升小目标的检测效果
  • 【数据结构与算法】数据结构初阶:详解顺序表和链表(三)——单链表(上)
  • OpenCV实现感知哈希(Perceptual Hash)算法的类cv::img_hash::PHash
  • 商城网站建设实务
  • Ragflow-plus本地部署和智能问答及报告编写应用测试
  • 标准化模型格式ONNX介绍:打通AI模型从训练到部署的环节
  • C语言易错点(二)
  • C++包管理工具:conan2常用命令详解
  • JVM-----【并发可达性分析】
  • Android 12系统源码_分屏模式(一)从最近任务触发分屏模式
  • 微信小程序核心知识点速览
  • OpenCV图像基本操作:读取、显示与保存