Tải bản đầy đủ - 0 (trang)
Chapter 56.  Whenever it makes sense, provide a no-fail swap (and provide it correctly)

Chapter 56.  Whenever it makes sense, provide a no-fail swap (and provide it correctly)

Tải bản đầy đủ - 0trang

Summary

swapisbothalightweightandaworkhorse:Considerproviding

aswapfunctiontoefficientlyandinfalliblyswaptheinternalsof

thisobjectwithanother's.Suchafunctioncanbehandyfor

implementinganumberofidioms,fromsmoothlymoving

objectsaroundtoimplementingassignmenteasilytoproviding

aguaranteedcommitfunctionthatenablesstronglyerror-safe

callingcode.(SeealsoItem51.)



Discussion

Aswapfunctiontypicallylookslikethis,whereUissomeuserdefinedtype:

classT{//

public:

voidswap(T&rhs){

member1_.swap(rhs.member1_);

std::swap(member2_,rhs.member2_);

}

private:

Umember1_;

intmember2_;

};



Forprimitivetypesandforstandardcontainers,std::swapwill

do.Otherclassesmightimplementswappingasamember

functionundervariousnames.

Considerusingswaptoimplementcopyassignmentintermsof

copyconstruction.Thefollowingimplementationofoperator=

providesthestrongguarantee(seeItem71),althoughatthe

priceofcreatinganextraobject,whichcanbeinappropriateif

therearemoreefficientwaystoperformerror-safeassignment

forTobjects:



T&T::operator=(constT&other){//good:Variant#1(tradi

Ttemp(other);

swap(temp);

return*this;

}

T&T::operator=(Ttemp){//good:Variant#2(seeI

swap(temp);//note:temppassedbyvalu



return*this;

}



WhatifUdoesnotimplementano-failswapfunction,asisthe

casewithmanylegacyclasses,andyoustillneedTtosupporta

swapfunction?Allisnotlost:

IfU'scopyconstructorandcopyassignmentdon'tfail(as,

again,mightbethecasewithlegacyclasses),std::swap

willworkfineonUobjects.

IfU'scopyconstructormightfail,youcanstorea(smart)

pointertoUinsteadofadirectmember.Pointersareeasily

swappable.Theydoincurtheadditionaloverheadofone

extradynamicstorageallocationandoneextraaccess

indirection,butifyoustoreallsuchmembersinasingle

Pimplobjectyou'llincurtheoverheadonlyonceforall

privatemembers.(SeeItem43.)

Neverusethetrickofimplementingcopyassignmentinterms

ofcopyconstructionbyusinganexplicitdestructorfollowedby

placementnew,eventhoughthistrickstillcropsupregularlyin

C++forums.(SeealsoItem99.)Thatis,neverwrite:



T&T::operator=(constT&rhs){//bad:ananti-id

if(this!=&rhs){

this->~T();//thistechnique

new(this)T(rhs);//(see[Sutter00]

}

return*this;

}



Prefertoprovideanonmemberswapfunctioninthesame

namespaceasyourtypewhenobjectsofyourtypehaveaway

toexchangetheirvaluesmoreefficientlythanviabrute-force

assignment,suchasiftheyhavetheirownswaporequivalent

function(seeItem57).Additionally,considerspecializing

std::swapforyourownnontemplatetypes:



namespacestd{

template<>voidswap(MyType&lhs,MyType&rhs){//forMyT

lhs.swap(rhs);//useMyT

}

}



ThestandarddoesnotallowyoutodothiswhenMyTypeisitself

atemplateclass.Fortunately,thisspecializationisjustaniceto-have;theprimarytechniqueistoprovideatype-customized

swapasanonmemberinthesamenamespaceasthetype.



Exceptions

Swappingisvaluableforclasseswithvaluesemantics.Itisless

oftenusefulforbaseclassesbecauseyouusethoseclasses

throughpointersanyway.(SeeItems32and54.)



References

[C++03]Đ17.4.3.1(1)[Stroustrup00]ĐE.3.3[Sutter00]

Đ12-13,Đ41



NamespacesandModules

Systemshavesub-systemsandsub-systemshave

sub-systemsandsoonadinfinitumwhichiswhy

we'realwaysstartingover.

AlanPerlis

Thenamespaceisanimportanttoolformanagingnames

andreducingnamecollisions.Soisamodule,whichis

additionallyanimportanttoolformanagingreleasesand

versioning.Wedefineamoduleasanycohesiveunitof

release(seeItem5)maintainedbythesamepersonor

team;typically,amoduleisalsoconsistentlycompiled

withthesamecompilerandswitchsettings.Modulesexist

atmanylevelsofgranularitythatrangewidelyinsize;a

modulecanbeassmallasasingleobjectfilethatdelivers

asingleclass,toasinglesharedordynamiclibrary

generatedfrommultiplesourcefileswhosecontentsform

asubsysteminsidealargerapplicationorarereleased

independently,toaslargeasahugelibrarycomposedof

manysmallermodules(e.g.,sharedlibraries,DLLs,or

otherlibraries)andcontainingthousandsoftypes.Even

thoughsuchentitiesassharedlibrariesanddynamic

librariesarenotmentioneddirectlyintheC++Standard,

C++programmersroutinelybuildanduselibraries,and

goodmodularizationisafundamentalpartofsuccessful

dependencymanagement(seeforexampleItem11).

It'shardtoimagineaprogramofanysignificantsizethat

doesn'tusebothnamespacesandmodules.Inthis

section,wecoverbasicguidelinesonusingthesetwo

relatedmanagementandbundlingtoolswithaviewto

howtheyinteractwellorbadlywiththerestoftheC++

languageandrun-timeenvironment.Theserulesand



guidelinesshowhowtomaximizethe"well"andavoidthe

"badly."

OurvoteforthemostvaluableIteminthissectiongoesto

Item58:Keeptypesandfunctionsinseparate

namespacesunlessthey'respecificallyintendedtowork

together.



57.Keepatypeanditsnonmember

functioninterfaceinthesame

namespace

Summary

Discussion

Examples

References



Summary

Nonmembersarefunctionstoo:Nonmemberfunctionsthatare

designedtobepartoftheinterfaceofaclassX(notably

operatorsandhelperfunctions)mustbedefinedinthesame

namespaceastheXinordertobecalledcorrectly.



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 56.  Whenever it makes sense, provide a no-fail swap (and provide it correctly)

Tải bản đầy đủ ngay(0 tr)

×