C++运算符重载中的引用返回

文章目录

  • 引言
  • 原因
    • 1.为了支持链式调用
    • 2.避免不必要的对象创建和复制
    • 3.保持语义一致性

引言

在C++编程语言中,运算符重载是一项强大的特性,它允许程序员为自定义类型重新定义或重载已有的运算符,从而使得这些类型能够像内置类型一样使用运算符。这不仅提高了代码的可读性和易用性,还使得复杂的操作可以通过简洁的语法来表达。而在运算符重载的过程中,返回值的类型选择是一个重要的设计决策,其中引用返回尤为关键。

引用返回在C++运算符重载中扮演着至关重要的角色。通过返回引用,我们可以实现链式操作、修改原始对象状态以及避免不必要的对象复制等。这些特性使得引用返回在构建高效、灵活的C++代码时成为不可或缺的工具。

然而,引用返回也带来了一些潜在的问题和挑战。例如,如果不正确地使用引用返回,可能会导致程序出现难以察觉的错误或不可预测的行为。因此,在使用引用返回时,我们需要仔细考虑其适用的场景和潜在的风险,并遵循一些最佳实践来确保代码的正确性和可靠性。


原因

以下是一个具体的例子,展示了为什么重载有些运算符时要返回自身的引用:

class MyClass {
public:
    int value;
    MyClass(int v = 0) :value(v) {
         std::cout << " MyClass(int v) " << std::endl;
    }
    MyClass(const MyClass& v) :value(v.value) {
        std::cout << " MyClass(const MyClass& v) " << std::endl;
    }
    ~MyClass() {
        std::cout << " ~MyClass() " << std::endl;
    }
    // 重载赋值运算符,返回自身的引用  
    MyClass& operator=(const MyClass& other) {
        if (this != &other) { // 防止自赋值  
            value = other.value;
        }
        return *this; // 返回自身的引用  
    }
    MyClass& operator+=(const MyClass& other) {
        value += other.value;
        return *this; // 返回自身的引用  
    }
};

int main() {
    MyClass a(10);
    MyClass b(20);
    MyClass c(30);

    // 使用链式赋值   
    a += b += c;
    std::cout << a.value << std::endl; 	//60
    std::cout << b.value << std::endl;	//50
    std::cout << c.value << std::endl	//30
	a = b =c; // 输出a的值,应为30,因为a = b = c;相当于a = (b = c);  
    std::cout << a.value << std::endl;	//30
    std::cout << b.value << std::endl;	//30
    std::cout << c.value << std::endl;	//30
    return 0;
}

1.为了支持链式调用

在这个例子中,MyClass 类重载了赋值运算符,使其返回自身的引用。在 main 函数中,a = b = c; 语句使用了链式赋值。首先,c 的值赋给 b,然后 b 的值(现在已经被赋值为 c 的值)再赋给 a。由于赋值运算符返回了 MyClass类型,这使得链式赋值成为可能。

但是如若我们返回值改为void

void MyClass::operator+=(const MyClass& other) {
    value += other.value;
}

// 使用链式赋值   
a = b;
b = c;
a += b += c;
//error C2679: 二元“+=”: 没有找到接受“void”类型的右操作数的运算符(或没有可接受的转换)

返回引用使得链式调用成为可能。例如,在a += b += c;这样的语句中,b += c首先执行,并返回b对象的引用。然后,这个返回的引用被用于a +=操作。如果operator+=不返回本类型变量,而是返回void,那么a +=将不会正确地工作。

2.避免不必要的对象创建和复制

如果operator+=operator=返回一个对象而不是引用,我们修改代码:

MyClass MyClass::operator+=(const MyClass& other) {
    value += other.value;
    return *this; // 返回自身的引用  
}

int main(){
    MyClass a(10);
    MyClass b(20);
    MyClass c(30);
    a += b += c;
}

运行结果:
在这里插入图片描述

那么每次调用该运算符时都会创建一个新的临时对象来存储结果。这不仅增加了内存分配和释放的开销,还可能导致不必要的对象复制,降低了代码的效率。通过返回引用,我们可以直接修改并返回原始对象,避免了这些额外的开销。

3.保持语义一致性

在C++中,内置的运算符(如+=)通常返回其左侧操作数的引用。对于自定义类型,重载这些运算符以返回引用可以保持与内置类型相似的行为,这有助于保持代码的语义一致性和可读性。

是的,在C++中,对于自定义类型,重载运算符时返回引用是一个常见的做法,特别是针对类似+=、-=等复合赋值运算符。通过返回左侧操作数的引用,可以实现链式调用和保持与内置类型相似的行为,增强代码的可读性和一致性。

例如,如果我们有一个自定义的Vector类,并希望支持向量的加法操作,可以这样重载+=运算符:

class Vector {
private:
    int x, y;

public:
    Vector(int x, int y) : x(x), y(y) {}// 重载 += 运算符
    Vector& operator+=(const Vector& other) {
        x += other.x;
        y += other.y;
        return *this; // 返回左侧操作数的引用
    }
};

通过返回*this(即左侧操作数)的引用,我们可以像内置类型一样使用+=运算符,并支持链式调用:

Vector v1(1, 2);
Vector v2(3, 4);
v1 += v2 += Vector(5, 6);

这样做不仅使代码更易读和直观,还能保持与内置类型的行为一致性,提高代码的可维护性和可读性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/489744.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数学建模之MATLAB使用

1.数值计算和符号计算的认识 我们都知道MATLAB里面存在着数值计算和符号计算&#xff0c;但是两者之间到底是怎样的呢&#xff1f; 举一个很简单的例子&#xff0c;我们在高等数学里面的微积分学习时经常求不定积分&#xff0c;也就是原函数&#xff0c;这个过程实际上进行的…

javaWeb学生宿舍管理系统

一、摘要 本博客介绍了如何使用Spring Boot和MySQL构建一个功能完善的JavaWeb学生宿舍管理系统。该系统分为三个角色&#xff1a;管理员、宿管和学生。管理员拥有对整个系统的全面管理权限&#xff0c;包括学生管理、宿舍管理、入住管理和管理员管理&#xff1b;宿管负责宿舍的…

高级 IO

1、五种IO模型 阻塞IO: 在内核将数据准备好之前, 系统调用会一直等待. 所有的套接字, 默认都是阻塞方式&#xff1b; 阻塞IO是最常见的IO模型&#xff1b; 非阻塞IO: 如果内核还未将数据准备好, 系统调用仍然会直接返回, 并且返回EWOULDBLOCK错误码&#xff1b; 非阻塞IO往往…

QMT量化交易上手

文章目录 QMT介绍基本使用代码初始化股票和行情交易量化策略示例相关链接QMT介绍 QMT是迅投公司出品量化交易客户端软件,目前只能运行在windows机器上,分为QMT 和 miniQMT两种模式,后者可以采用python API做程序化交易,极大方便了广大散户。这点上比同花顺/通信达好很多。…

Filter、Listener、AJAX

Filter 概念&#xff1a;Filter 表示过滤器&#xff0c;是JavaWeb三大组件(Servlet、Filter、 Listener)之一。 过滤器可以把对资源的请求拦截下来&#xff0c;从而实现一些特殊的功能。 过滤器一般完成一些通用的操作&#xff0c;比如&#xff1a;权限控制、统一编码处理、敏感…

百度谷歌301强引蜘蛛池效果怎么样

301强引蜘蛛池效果怎么样 本文 虚良SEO 原创&#xff0c;转载保留链接&#xff01;网址&#xff1a;百度谷歌301强引蜘蛛池效果怎么样 - 虚良SEO 随着搜索引擎优化&#xff08;SEO&#xff09;技术的发展&#xff0c;越来越多的网站开始采用蜘蛛池技术来提高网站的排名和流量。…

电脑如何一键修复所有dll缺失,几种修复dll文件丢失的方法

修复所有DLL&#xff08;动态链接库&#xff09;文件缺失的问题通常不可能通过单一的"一键修复"按钮来实现&#xff0c;因为DLL文件缺失可能由各种不同的原因导致&#xff0c;比如应用程序安装不正确、病毒感染、或系统文件损坏等。 使用内置的系统文件检查器&#x…

科东软件鸿道IntewellV2.3.2版本发布说明

一、软件发布版本信息 版本号&#xff1a;V2.3.2版本发布类型&#xff1a;beta受限版本 二、版本特点 1.合并分支代码 2.RTOS支持X86 64位 三、运行环境推荐 Intewell developer可以运行在windows7及windows10 64位 四、支持硬件列表

覃超老师 算法面试通关40讲

教程介绍 无论是阿里巴巴、腾讯、百度这些国内一线互联网企业&#xff0c;还是 Google、Facebook、Airbnb 等硅谷知名互联网公司&#xff0c;在招聘工程师的过程中&#xff0c;对算法和数据结构能力的考察都是重中之重。本课程以帮助求职者在短时间内掌握面试中最常见的算法与…

软件测试工程师这样面试,90%能拿到offer

如果大家有关注一些测试类的文章的话&#xff0c;肯定会发现很多人都在表示今年行业受到疫情的影响&#xff0c;工作很难找&#xff0c;那情况真的是如此么?你只是不知道面试官的意图是什么&#xff0c;不知道他考察你的点在哪里。只要弄明白面试中的一些固有套路&#xff0c;…

离线linux服务器安装mysql8

本文的服务器环境&#xff1a;openEuler毛坯版的&#xff0c;很多常用的指令都没有预装&#xff0c;比如rpm、tar等等&#xff0c;没有网络坏境&#xff0c;需要自己手动配置本地yum仓库&#xff0c;安装相关指令 1、检查服务器是否已经安装了MySQL 1.1、查询mysql以安装的相关…

uni-app中web-view的使用

1. uni-app中web-view的使用 uni-app中的web-view是一个 web 浏览器组件&#xff0c;可以用来承载网页的容器&#xff0c;uni-app开发的app与web-view实现交互的方式相关简单&#xff0c;应用通过属性message绑定触发事件&#xff0c;然后在web-view的网页向应用 postMessage 触…

docker使用教程

寒假用了docker 2个月没用 结果还重新安装docker 忘了怎么用 为了免得以后忘写下下面内容 # If you dont have a docker installed, youll need to install docker curl -s https://get.docker.com/ | sh # Use pip to install docker-compose pip install docker-compose…

西门子S7-1200/200 Smart的采集方式有哪些?如何快速采集?

​在工业自动化领域中&#xff0c;西门子S7-1200和S7-200 Smart系列PLC因其卓越的性能和广泛的应用而备受瞩目。为了实现对这些PLC设备的精准数据采集与远程控制&#xff0c;我们引入了HiWoo Box这一高效的工业物联网关。 一、采集西门子S7-1200/200 Smart数据的方式有哪些&am…

uniapp开发h5,引入微信开放标签实现h5跳转小程序功能,全网最全最细踩坑记录

先贴上微信开放标签的官方文档 一、概述流程 首先需要在项目中引入微信的sdk&#xff0c;具体引入方式详见我写的另一篇文章&#xff0c;里面包含了引入sdk以及配置wx.config的详细教学以及踩坑记录。如果引入完微信sdk的前提下接下来就是根据微信文档提供的demo来引入开放标…

绘图技巧 | 双变量映射地图可视化绘制方法

本期推文我们绘制不常见的双变量主题地图&#xff0c;该类地图可以很好的在地图上用颜色展示两个变量的信息&#xff0c;相较于单一变量映射地图&#xff0c;此类地图表达的信息更加丰富和全面。本期推文主要涉及的内容如下&#xff1a; 双变量映射地图(Bivariate Choropleth M…

商城小程序项目实现监控的可观测性最佳实践

前言 微信小程序是一种轻量级的应用程序&#xff0c;用户可以在微信内直接使用&#xff0c;无需下载安装。它具有独立的开发框架和生态系统&#xff0c;支持丰富的功能和交互&#xff0c;包括社交、购物、服务等。 观测云对微信小程序的监控能够实时收集性能指标、错误日志和…

su怎么做展厅模型---模大狮模型网

要在SketchUp中创建展厅模型&#xff0c;你可以按照以下基本步骤进行&#xff1a; 绘制基本结构&#xff1a; 使用SketchUp的绘图工具(线条、矩形、圆形等)来创建展厅的基本结构&#xff0c;包括墙壁、地板和天花板等。确保按照实际尺寸和比例进行绘制。 添加家具和展品&…

Mysql新建数据库报错1044

mysql创建数据库报错 1044 - Access denied for user ‘root‘%‘ to database ‘XXX‘ 解决参考&#xff1a;MySQL新建表&#xff1a;1044 - Access denied for user ‘root‘%‘ to database ‘XXX‘终极解决方案_cannot create table [sheet]: 1044 - access denied -CSDN博…

windows允许指定IP段访问本地端口

虚拟机内部应用有时候需要访问windows的一些端口&#xff0c;例如数据库或Redis等&#xff0c;默认情况下&#xff0c;需关闭windows上的防火墙才可正常访问。本文通过在防火墙设置允许指定IP段进行访问来处理&#xff0c;不用每次操作都关闭防火墙。 入站规则-》新建规则 完成…