Tải bản đầy đủ - 0 (trang)
Chapter 35.  Avoid inheriting from classes that were not designed to be base classes

Chapter 35.  Avoid inheriting from classes that were not designed to be base classes

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

Summary

Somepeopledon'twanttohavekids:Classesmeanttobeused

standaloneobeyadifferentblueprintthanbaseclasses(see

Item32).Usingastandaloneclassasabaseisaseriousdesign

errorandshouldbeavoided.Toaddbehavior,prefertoadd

nonmemberfunctionsinsteadofmemberfunctions(seeItem

44).Toaddstate,prefercompositioninsteadofinheritance(see

Item34).Avoidinheritingfromconcretebaseclasses.



Discussion

Usinginheritancewhenitisnotneededbetraysamisplaced

faithinthepowerofobjectorientation.InC++,youneedtodo

specificthingswhendefiningbaseclasses(seealsoItems32,

50,and54),andverydifferentandoftencontrarythingswhen

designingstandaloneclasses.Inheritingfromastandaloneclass

opensyourcodetoahostofproblems,veryfewofwhichwill

beeverflaggedbyyourcompiler.

Beginnerssometimesderivefromvalueclasses,suchasa

stringclass(thestandardoneoranother),to"addmore

functionality."However,definingfree(nonmember)functionsis

vastlysuperiortocreatingsuper_stringforthefollowing

reasons:

Nonmemberfunctionsworkwellwithinexistingcodethat

alreadymanipulatesstrings.Ifinsteadyousupplya

super_string,youforcechangesthroughoutyourcode

basetochangetypesandfunctionsignaturesto

super_string.

Interfacefunctionsthattakeastringnowneedto:a)stay

awayfromsuper_string'saddedfunctionality(unuseful);

b)copytheirargumenttoasuper_string(wasteful);orc)

castthestringreferencetoasuper_stringreference

(awkwardandpotentiallyillegal).

super_string'smemberfunctionsdon'thaveanymore

accesstostring'sinternalsthannonmemberfunctions

becausestringprobablydoesn'thaveprotectedmembers

(remember,itwasn'tmeanttobederivedfrominthefirst

place).



Ifsuper_stringhidessomeofstring'sfunctions(and

redefininganonvirtualfunctioninaderivedclassisnot

overriding,it'sjusthiding),thatcouldcausewidespread

confusionincodethatmanipulatesstringsthatstarted

theirlifeconvertedautomaticallyfromsuper_strings.

So,prefertoaddfunctionalityvianewnonmemberfunctions

(seeItem44).Toavoidnamelookupproblems,makesureyou

puttheminthesamenamespaceasthetypetheyaremeantto

extend(seeItem57).Somepeopledislikenonmember

functionsbecausetheinvocationsyntaxisFun(str)insteadof

str.Fun(),butthisisjustamatterofsyntactichabitand

familiarity.(Thenthere'sthesoundbite,attributedtothe

legendaryAlanPerlis,thattoomuchsyntacticsugarcauses

cancerofthesemicolon.)

Whatifsuper_stringwantstoinheritfromstringtoadd

morestate,suchasencodingoracachedwordcount?Public

inheritanceisstillnotrecommended,becausestringisnot

protectedagainstslicing(seeItem54)andsoanycopyingofa

super_stringtoastringwillsilentlychopoffallofthe

carefullymaintainedextrastate.

Finally,inheritingfromaclasswithapublicnonvirtual

destructorriskslitteringyourcodewithundefinedbehaviorby

delete-ingpointerstostringthatactuallypointto

super_stringobjects(seeItem50).Thisundefinedbehavior

mightseemtobetoleratedbyyourcompilerandmemory

allocator,butitleavesyouinthedarkswampofsilenterrors,

memoryleaks,heapcorruptions,andportingnightmares.



Examples

Example:Compositioninsteadofpublicorprivateinheritance.

Whatifyoudoneedalocalized_stringthatis"almostlike

string,butwithsomemorestateandfunctionsandsome

tweakstoexistingstringfunctions,"andmanyfunctions'

implementationswillbeunchanged?Thenimplementitinterms

ofstringsafelybyusingcontainmentinsteadofinheritance

(whichpreventsslicingandundefinedpolymorphicdeletion),

andaddpassthroughfunctionstomakeunchangedfunctions

visible:



classlocalized_string{

public:

//providepassthroughstostringmemberfunctionthatwew

//retainunchanged(e.g.,defineinsertthatcallsimpl_.ins

voidclear();//mask/redefi

boolis_in_klingon()const;//addfunctio

private:

std::stringimpl_;

//addextrastate

};



Admittedly,it'stedioustohavetowritepassthroughfunctions

forthememberfunctionsyouwanttokeep,butsuchan

implementationisvastlybetterandsaferthanusingpublicor

nonpublicinheritance.



References

[Dewhurst03]Đ70,Đ93[Meyers97]Đ33[Stroustrup00]

Đ24.2-3,Đ25.2



36.Preferprovidingabstractinterfaces

Summary

Discussion

Examples

Exceptions

References



Summary

Loveabstractart:Abstractinterfaceshelpyoufocusongetting

anabstractionrightwithoutmuddlingitwithimplementationor

statemanagementdetails.Prefertodesignhierarchiesthat

implementabstractinterfacesthatmodelabstractconcepts.



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

Chapter 35.  Avoid inheriting from classes that were not designed to be base classes

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

×