更新时间:2020-02-26 09:23:31 来源:极悦 浏览2016次
C.60:Makecopyassignmentnon-virtual,taketheparameterbyconst&,andreturnbynon-const&
C.60:拷贝赋值运算符应该是以const&为参数,返回非常量引用类型的非虚函数
Reason(原因)
Itissimpleandefficient.Ifyouwanttooptimizeforrvalues,provideanoverloadthattakesa&&(seeF.18).
因为这样简单且高效。如果你希望对右值优化,提供一个使用&&(右值引用)的重载。
Example(示例)
classFoo{public:Foo&operator=(constFoo&x){//GOOD:noneedtocheckforself-assignment(otherthanperformance)autotmp=x;swap(tmp);//seeC.83return*this;}//...};Fooa;Foob;Foof();a=b;//assignlvalue:copya=f();//assignrvalue:potentiallymove
Note(注意)
Theswapimplementationtechniqueoffersthestrongguarantee.
实现交换函数(参考C.83)的技术提供了(不会发生自拷贝,译者注)强有力的保证。
Example(示例)
Butwhatifyoucangetsignificantlybetterperformancebynotmakingatemporarycopy?ConsiderasimpleVectorintendedforadomainwhereassignmentoflarge,equal-sizedVectorsiscommon.Inthiscase,thecopyofelementsimpliedbytheswapimplementationtechniquecouldcauseanorderofmagnitudeincreaseincost:
但是能不能通过少进行一次临时的拷贝动作来得到明显更高的性能呢?考虑用于(元素,译者注)大小相同的巨大Vector赋值的简单的Vector的场景。在这种情况下,通过swap技术实现的元素拷贝动作将引起成本的大幅度增加。
译者注
前面的例子,在swap之前进行了一次拷贝构造
template<typenameT>classVector{public:Vector&operator=(constVector&);//...private:T*elem;intsz;};Vector&Vector::operator=(constVector&a){if(a.sz>sz){//...usetheswaptechnique,itcan'tbebettered...return*this;}//...copyszelementsfrom*a.elemtoelem...if(a.sz<sz){//...destroythesurpluselementsin*thisandadjustsize...}return*this;}
Bywritingdirectlytothetargetelements,wewillgetthebasicguaranteeratherthanthestrongguaranteeofferedbytheswaptechnique.Bewareofself-assignment.
通过将数据直接写入对象元素,我们可以得到基本的保证而不是通过swap技术提供的强保证。为了防止自己给自己赋值。
Alternatives(可选项)
Ifyouthinkyouneedavirtualassignmentoperator,andunderstandwhythat'sdeeplyproblematic,don'tcallitoperator=.Makeitanamedfunctionlikevirtualvoidassign(constFoo&).Seecopyconstructorvs.clone().
如果你认为你需要一个虚赋值操作运算符,而且理解它会产生很深刻的问题,别把设计成赋值运算符。将它定义为具名函数,例如virtualvoidassign(constFoo&)。
拷贝构造vs克隆的链接:
http://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rc-copy-virtual
Enforcement(实施建议)
(Simple)Anassignmentoperatorshouldnotbevirtual.Herebedragons!(简单)赋值运算符不应该是虚函数。那样做很危险。
(Simple)AnassignmentoperatorshouldreturnT&toenablechaining,notalternativeslikeconstT&whichinterferewithcomposabilityandputtingobjectsincontainers.(简单)赋值运算符应该返回T&,这样才能实现连续赋值。不要改成类似constT&的类型,这样会影响组装性并妨碍将对象放进容器中。
(Moderate)Anassignmentoperatorshould(implicitlyorexplicitly)invokeallbaseandmemberassignmentoperators.Lookatthedestructortodetermineifthetypehaspointersemanticsorvaluesemantics.(中等)赋值运算符应该(隐式或显式)调用所有的基类和成员的赋值运算符。观察析构函数以决定这个类型式指针语义还是值语义。
以上就是极悦注册机构小编介绍的“JavaSE入门到精通视频:赋值运算符的三个注意事项”的内容,希望对大家有帮助,如有疑问,请在线咨询,有专业老师随时为你服务。
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习