首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么不在operator=中返回常量引用而不是引用呢?

在operator=中返回常量引用而不是引用的原因是为了避免潜在的错误和不一致性。当我们在重载赋值运算符时,通常会将其定义为返回一个引用,以便支持连续赋值操作。然而,如果我们返回一个常量引用,那么在连续赋值操作中,每次赋值都会返回一个新的常量引用,而不是原始对象的引用。

这样做可能会导致一些问题。首先,返回常量引用会导致无法修改赋值运算符的左操作数,因为常量引用只能用于读取,而不能用于写入。这违背了赋值运算符的本意,即修改左操作数的值。

其次,返回常量引用可能会导致资源泄漏。如果在连续赋值操作中返回常量引用,每次赋值都会创建一个新的常量引用,而不是释放之前的引用。这样一来,我们就无法释放之前的资源,从而导致内存泄漏或其他资源泄漏问题。

因此,为了避免这些问题,通常在operator=中返回非常量引用,以便支持连续赋值操作,并确保正确地修改左操作数的值。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

为什么 C# 的 string.Empty 是一个静态只读字段,不是一个常量

使用 C# 语言编写字符串常量的时候,你可能会发现可以使用 "" 不能使用 string.Empty。...进一步可以发现 string.Empty 实际上是一个静态只读字段,不是一个常量为什么这个看起来最适合是常量的 string.Empty,竟然使用静态只读字段?...也就是说,string.Empty 字段并不是一个普通的字段,对它的调用会被特殊处理。但是是如何特殊处理?...string.Empty 需要是一个静态只读字段不是常量?...当然,事实上编译器也可以针对此场景做特殊处理,但为什么不是在编译这一层进行特殊处理,我已经找不到出处了。 本文引申的其他问题 能否反射修改 string.Empty 的值? 不行!

1.1K00

C++临时变量的常量

2.临时变量常量性的原因 为什么临时对象作为引用参数传递时,形参必须是常量引用?很多人对此的解释是临时变量是常量,不允许赋值改动,所以作为非常量引用传递时,编译器就会报错。...IntClass(6)表示生成一个无名临时变量并作为左值被修改,所以临时变量并不是常量,只是编译器从语义层面限制了临时变量传递给非const引用。...注意,这里与《C++编程思想》在第八章的“临时量”小节认为“编译器使所有的临时量自动设为const”的说法有些不同。 那编译器为何作出如此限制?...如果一个实参以非const引用传入函数,编译器有理由认为该实参会在函数中被修改,并且这个被修改的引用在函数返回后要发挥作用。...---- 参考文献 [1]c++临时变量不能作为非const的引用参数 [2]C++编程思想[M].刘宗田译.8.3.2.1临时量

1.9K31

C++实战——日期类的实现

该函数采用了常量引用参数const Date& d,表示传递给该函数的参数d是一个常量引用,即不会对d进行修改。这是为了保证在比较函数不会对传入的对象进行修改。...该函数采用了常量引用参数const Date& d,表示传递给该函数的参数d是一个常量引用,即不会对d进行修改。这是为了保证在比较函数不会对传入的对象进行修改。...该函数采用了常量引用参数const Date& d,表示传递给该函数的参数d是一个常量引用,即不会对d进行修改。这是为了保证在比较函数不会对传入的对象进行修改。...最后返回tmp对象,也就是自减之前的值。 需要注意的是,返回的是一个临时对象的引用不是自身的引用。这是因为后置递减运算符需要返回自减之前的值,不是自减之后的值。...为了防止出现悬空引用的情况,使用临时对象来保存自减之前的值,并返回引用。 关于类里重载的比较运算符为什么要加外部const 在C++,比较运算符重载通常需要将其定义为成员函数。

7710

【C++11】右值引用和移动语义

左值引用和右值引用 传统的C++语法中就有引用的语法,C++11新增了的右值引用语法特性,所以从现在开始我们之前学习的引用就叫做左值引用。 无论左值引用还是右值引用,都是给对象取别名。...这个了解一下实际右值引用的使用场景并不在于此,这个特性也不重要。 1.4 思考 左值引用可以给右值取别名(引用右值)吗?...但是右值引用可以move以后的左值。 那从上面的内容来看: 左值引用其实既可引用左值,也可引用右值(加const就行了) 那为什么还要搞出右值引用?有什么意义? 3....右值引用的使用场景和意义 前面我们可以看到左值引用既可以引用左值和又可以引用右值,那为什么C++11还要提出右值引用?是不是画蛇添足?...然后第二个push_back 常量字符串也是右值。

13610

终极 C++避坑指南

return tmp;   }  private:   int ele; }; 这也从侧面解释了,为什么前置++要求返回引用,而后置++则是返回引用,因为这里需要复制一份快照用于返回。...const 引用 先说说 const 先来吐槽一件事,就是 C/C++const这个关键字,这个名字起的非常非常不好!为什么这样说?...我们再来看看右值引用绑定变量的情况: 这里的关键问题在于,什么样的变量适合用右值引用绑定? 如果对于普通的变量,C++不允许用右值引用来绑定,但这是为什么?...总结来说就是,右值引用绑定常量时相当于“给一个常量提供了生命周期”,这时的“右值引用”并不是谁的引用,而是相当于一个普通变量;右值引用绑定将亡对象时,相当于“给将亡对象延长了生命周期”,这时的“右值引用...那么私有继承既然是用来表示组合关系的,那我们为什么不直接用成员对象为什么要使用私有继承?这是因为用成员对象在某种情况下是有缺陷的。

2.1K20

临时变量作为非const的引用进行参数传递引发的编译错误

其中文意思为临时变量无法为非const的引用初始化。也就是在参数传递的过程,出现错误。...---- 2.所有的临时对象都是const对象吗 为什么临时对象作为引用参数传递时,必须是常量引用?很多人对此的解释是临时对象是常量,不允许赋值改动,所以作为非常量引用传递时,编译器就会报错。...IntClass(6)表示生成一个无名的临时对象,传递给非const引用,在print函数通过引用修改了这个临时对象。这说明了并非所有的临时对象都是const对象。...那哪些临时对象是const对象,哪些临时对象不是const对象?...这里贴上摘自网上的一句话:“内置类型产生的临时变量具有常性,自定义类型产生的临时变量不具有常性”,我想这句话能解释你所谓的临时变量为什么能作为左值的原因。”

2.4K31

C++运算符重载详解

} }; 从上面的例子可以看出: 函数的返回都是普通类型不是引用类型是因为这些运算符计算出来的结果都和输入的数据并不是相同的对象而是一个临时对象,因此不能返回引用类型,也就是不能再作为左值使用。...因此这种运算符函数的第一个参数必须是引用类型,不能是常量,同时返回类型要和第一个参数的类型一致。...,因此左边参数不能是常量只能是引用类型。...这里返回不是值类型而是引用类型的目的是为了减少因为读取产生不必要的内存复制。写入操作则必须使用引用类型。 8....那么为什么要让对象来提供函数的能力?答案就是我们可以在对象的函数运算符内部访问一些对象本身具有的其他属性或者其他成员函数,普通的函数则不具备这些特性。

1.4K30

《挑战30天C++入门极限》C++运算符重载函数基础及其值返回状态

我们让重载后的加运算符做的事情,事实上并不是同类型对象的加运算,而是自定义类对象与内置int常量对象的乘法运算。   ...//如果把该函数改成返回值,不是返回引用的话就破坏了单目预算改变自身的特点,程序的++(++c)运算结束后输出c.a,会发现对象c只做了一次递增运算,原因在于,当函数是值返回状态的时候括号内的++c...,细心的读者会发现加运算和递增运算重载函数少了一个参数,这是为什么?   ...,但是在main()函数++(++c);的执行结果却出乎意料,理论上应该是204的值,却只是203,这是为什么?   ...因为当函数是值返回状态的时候括号内的++c返回不是c本身而是临时变量,用临时变量参与括号外的++运算,当然c的值也就只改变了一次。结果为203不是204。

49420

【C++】右值引用(极详细版)

右值准确来说是:一个表示数据的表达式(如字面常量、函数的返回值、表达式的返回值),且不可以获取他的地址(取地址);它只能在赋值符号的右边。 右值也是通常不可以改变的值。...所以这也就是为什么出现了右值引用,当然这是是右值引用价值的一个! 那在没有右值引用之前,我们是如何解决函数传返回值的拷贝问题?...再举一个例子: 右值分为:纯右值(字面常量)和将亡值(更侧重于自定义类型的函数的返回值,表达式的返回值)。 当构造传左值,就走拷贝构造,当构造传右值,就走移动构造。...所以我们会想,有没有这么一个东西,自动去识别我们传的参数是左值还是右值,不会因为右值引用改变右值属性。...我们继续往下看 1.万能引用 当并不明确规定传右值或者左值时:  万能引用在这里起到了用处,可以随便传。(也叫做折叠)模板的&&不是右值引用,而是为了万能引用,可以折叠。

65520

【C++修炼之路】27.右值引用

1.2 右值和右值引用 右值也是一个表示数据的表达式,如:字面常量、表达式返回值,函数返回值(这个不能是左值引用返回)等等,右值可以出现在赋值符号的右边,但是不能出现出现在赋值符号的左边,右值不能取地址...如果不想rr1被修改,可以用const int&& rr1去引用。但实际右值引用的使用场景并不在于此,这根特性也不重要。...tmp的构造,第一次的深拷贝实际上不是深拷贝,只是进入的一个标志,即实际上只进行了一次深拷贝。...我们也发现,调试会进入到赋值运算符重载,那如果将赋值运算符重载函数再重载一个右值引用的版本——即移动赋值,是不是就可以解决了?...六.const修饰的右值引用 6.1 右值引用变量的属性 我们知道,左值引用可以修改,const修饰的左值引用不能修改。但是对于右值引用来说,右值本身就不能修改,为什么还要加上const

24700

剖析深拷贝与浅拷贝,探究重载返回引用还是对象

} 上述分别是前置++重载操作符与后置++操作符重载,可以有个疑惑,为何前置返回的是引用而后置返回的是对象?...只不过赋值函数最好有返回值(进行链式赋值),返回也最好是对象的引用拷贝函数不需要返回任何。...同时,赋值函数首先要释放掉对象自身的堆空间(如果需要的话),然后进行其他的operation.拷贝函数不需要如此,因为对象此时还没有分配堆空间。 2.C++中有些重载运算符为什么返回引用?...(一个临时对象,str3的一个拷贝),不是引用,所以此时str3不在后面的=str1的操作,而是str1对一个临时对象赋值,所以str3的内容保持不变(等于str2)。...总结 那么什么情况下要返回对象的引用

83240

左值和右值、左值引用与右值引用、移动语句(2)「建议收藏」

它可以是函数的名称或取消引用函数指针的结果。 C语言还区分它对函数指针和对象指针的处理。 另一方面,在C ++返回引用的函数调用是左值。否则,函数调用是rvalue表达式。...将亡值 在C++11之前的右值和C++11的纯右值是等价的。C++11的将亡值是随着右值引用的引入新引入的。换言之,“将亡值”概念的产生,是由右值引用的产生引起的,将亡值与右值引用息息相关。...;9.str1+str2是调用了+操作符,+操作符返回的是一个string(不可以对其取地址),故其为右值;10.m是一个常量引用引用到一个右值,但引用本身是一个持久对象(可以对其取地址),为左值。...那么,为什么要对非常量右值进行区分,区分出来了又有什么好处?这就牵涉到C++中一个著名的性能问题——拷贝临时对象。...这是因为在move构造函数,s虽然是一个非常量右值引用,但其本身却是一个左值(是持久对象,可以对其取地址),因此调用*this = s时,会使用拷贝赋值函数不是move赋值函数,而这已与move构造函数的语义不相符

2.5K20

【C++】类和对象之常引用与运算符重载

z是常量的别名了。 还可以有这样的。 但是像下面这样就不行,因为临时变量具有常性,不能被修改。 这里是权限的放大,a+x表达式的返回值是临时对象。...但传引用就不行,因为类型不同。 但是加了const就行,为什么? 因为类型转换中间会有临时变量。 这里严格来说不是把d给i,然后d构造的临时变量拷贝给i。...下面的引用也是一样的,是把d拷贝给临时变量,ri是这个临时变量的别名,因为临时变量具有常性,所以用常引用。 那么为什么要产生临时变量? 这里i和ch比较为什么会相等?...函数原型:返回值类型 operator操作符(参数列表) class Date { public: Date(int year = 1900, int month = 1, int day = 1)...为什么这里实现结果是一样的? 因为编译器会给去调用对应的函数。 但是在实践私有变量肯定不是像上面代码一样。在类外面是不能访问的,那怎么办? 类外面不能服务,那么就放到类里面。

10610

性能优化-字符串(String)

使用String str=new String("ab") 这种方式在类编译的时候,字符串在常量池创建,然后使用new String(),同时引用常量池的引用,且在堆创建一个string对象,再把这个字符串对象引用返回给...,默认会把对象放到常量池中,如果是字符串变量,会把在堆创建,同时在常量池创建一个字符串对象,String对象char数组会引用常量池中的char数组,并返回堆内存的引用....但是如果使用intern,会查看常量池是否有字符串对象的引用,如果有直接返回常量池的引用....如果没有,在1.6版本,会把堆的字符串复制到常量池中,并返回字符串的引用,此时堆没有指向他的引用,垃圾回收器回收此引用....如果在1.7版本以后,常量池合并到了堆,此时不会进行复制字符串,会把堆的字符串引用添加到常量池中. ? ?

68030

C++编程经验(8):对象优化,试试?试试就逝世哈哈哈

---- 接下来我们看函数调用的对象优化。...为什么这么说,咱凡事讲证据。...---- 还没完,捋清楚这些,不是好玩儿,是要做优化的,真正的优化,正要开始。 首先,不觉得从上到下都在讲的有:形参、回调,是吧,不觉得很多余吗?...---- 为什么回调会这么麻烦?因为当函数运行完的时候,temp生命周期也到头了呀!!! 所以需要在用一个临时变量去接住它,再传出来,再赋值。 那我现在不想这么麻烦了!!!...& d = 20; //非常量引用的对象必须为左值 const int& e = 20; //先生成了一个临时量,值为20,再用引用引用这个临时量 int&& f = 20; //用右值引用引用右值

26330

《C++Primer》第十四章 重载运算与类型转换

类需要自定义适合其对象的新版本以支持IO操作。...第二个形参一般是一个常量引用引用的原因是我们希望避免复制形参,常量是因为打印对象不会改变对象的内容。并且为了和其他输出运算符保持一致,operator<<一般要返回它的ostream形参。...与下标的原始定义兼容,我们需要确保: 下表运算符通常以所访问元素的引用作为返回值,这样下标可以出现在赋值运算符的任意一端 最好定义下标运算符的常量和非常量版本,当作用于一个常量对象时下标运算符返回常量引用以确保我们不会给返回的对象赋值...如果一个类包含下标运算符,那么它通常会定义两个版本:一个返回普通引用,另一个是类的常量成员并返回常量引用 class StrVec { public: std::string& operator...= si += 3; // 首先将si隐式地转换成int,然后执行整数的加法 在实践类很少提供类型转换运算符,在大多数情况下,如果类型转换自动发生,用户可能会感觉比较意外,不是感觉受到了帮助。

89810

【C++】深度剖析string类的底层结构及其模拟实现

为什么第10行这里打印就崩了不是返回一个空指针吗?那就打印空指针啊。 ,这里不是这样的,这里程序挂掉的原因就在于对返回的空指针解引用了。 为什么会解引用?...对象是可以被修改的,现在_str指向一个常量字符串,它有可能直接就是在常量区的,那我们后面扩容是不是也没法搞啊,而且这里还加了const,所以就修改不成了。...这样普通对象可以调,const对象是不是也可以调了。 那const对象调[ ]的话,const对象不能修改,所以我们返回引用返回const引用。...但是现在有一个新的问题: 现在普通对象和const对象都可以调[]了,这没问题,但是由于返回的const引用普通对象可以被修改的,那现在返回的const引用普通对象还能通过[]修改吗?...,释放s2的时候,就把引用计数减1,不是真的释放这块空间,等到s1释放的时候,引用计数为1,表示只有一个对象使用这块资源,就可以释放了。 那这个地方是不是不拷贝啊?

22110

【C++】C++11的常见语法(上)

什么是右值引用? 右值也是一个表示数据的表达式,如:字面常量、表达式返回值,函数返回值(这个不能是左值引用返回)等等,右值可以出现在赋值符号的右边,但是不能出现出现在赋值符号的左边,右值不能取地址。...,可以对 rr1 取地址,也可以修改 rr1;如果不想 rr1 被修改,可以用 const int&& rr1 去引用,是不是感觉很神奇,这个了解一下实际右值引用的使用场景并不在于此,这个特性也不重要...右值引用使用场景和意义 前面我们可以看到左值引用既可以引用左值和又可以引用右值,那为什么 C++11 还要提出右值引用?是不是画蛇添足?...那么为什么右值被右值引用引用以后的属性是左值?...注意,完美转发要和模板的万能引用搭配使用,因为如果不是万能引用,那么它就只能是普通的右值引用,此时左值不能传参。 所以完美转发的使用场景有哪些

14710

C++ 的左值和右值

一个引用是指向一个已经存在的内存位置(global变量)的东西,因此它是一个左值,所以它能被赋值。注意这里的&:它不是取地址操作符,他定义了返回的类型(一个引用)。...五、左值引用 相反?一个右值可以被转化为左值吗?不可以,它不是技术所限,而是C++编程语言就是那样设计的。...一个volitile的数字常量(右值)如果想要被引用,需要先变成一个左值。如果那被允许,你就可以通过它的引用来改变数字常量的值。相当没有意义,不是吗?...’ from an rvalue of type ‘int’ GCC认为引用不是const的,即一个常量。...同样,这不是一个技术限制,而是C ++人员为避免愚蠢麻烦所作的选择。 应用:C++中经常通过常量引用来将值传入函数,这避免了不必要的临时对象的创建和拷贝。

1.7K20
领券