Tải bản đầy đủ - 0 (trang)
Chapter 50.  Make base class destructors public and virtual, or protected and nonvirtual

Chapter 50.  Make base class destructors public and virtual, or protected and nonvirtual

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

Summary

Todelete,ornottodelete;thatisthequestion:Ifdeletion

throughapointertoabaseBaseshouldbeallowed,thenBase's

destructormustbepublicandvirtual.Otherwise,itshouldbe

protectedandnonvirtual.



Discussion

Thissimpleguidelineillustratesasubtleissueandreflects

modernusesofinheritanceandobject-orienteddesign

principles.

ForabaseclassBase,callingcodemighttrytodeletederived

objectsthroughpointerstoBase.IfBase'sdestructorispublic

andnonvirtual(thedefault),itcanbeaccidentallycalledona

pointerthatactuallypointstoaderivedobject,inwhichcase

thebehavioroftheattempteddeletionisundefined.Thisstate

ofaffairshasledoldercodingstandardstoimposeablanket

requirementthatallbaseclassdestructorsmustbevirtual.This

isoverkill(evenifitisthecommoncase);instead,therule

shouldbetomakebaseclassdestructorsvirtualifandonlyif

theyarepublic.

Towriteabaseclassistodefineanabstraction(seeItems35

through37).Recallthatforeachmemberfunctionparticipating

inthatabstraction,youneedtodecide:

Whetheritshouldbehavevirtuallyornot.

Whetheritshouldbepubliclyavailabletoallcallersusinga

pointertoBaseorelsebeahiddeninternalimplementation

detail.

AsdescribedinItem39,foranormalmemberfunction,the

choiceisbetweenallowingittobecalledviaaBase*

nonvirtually(butpossiblywithvirtualbehaviorifitinvokes

virtualfunctions,suchasintheNVIorTemplateMethod

patterns),virtually,ornotatall.TheNVIpatternisatechnique

toavoidpublicvirtualfunctions.

Destructioncanbeviewedasjustanotheroperation,albeitwith



specialsemanticsthatmakenonvirtualcallsdangerousor

wrong.Forabaseclassdestructor,therefore,thechoiceis

betweenallowingittobecalledviaaBase*virtuallyornotat

all;"nonvirtually"isnotanoption.Hence,abaseclass

destructorisvirtualifitcanbecalled(i.e.,ispublic),and

nonvirtualotherwise.

NotethattheNVIpatterncannotbeappliedtothedestructor

becauseconstructorsanddestructorscannotmakedeepvirtual

calls.(SeeItems39and55.)

Corollary:Alwayswriteadestructorforabaseclass,because

theimplicitlygeneratedoneispublicandnonvirtual.



Examples

Eitherclientsshouldbeabletodeletepolymorphicallyusinga

pointertoBase,ortheyshouldn't.Eachalternativeimpliesa

specificdesign:

Example1:Baseclasseswithpolymorphicdeletion.If

polymorphicdeletionshouldbeallowed,thedestructor

mustbepublic(elsecallingcodecan'tcallit)anditmustbe

virtual(elsecallingitresultsinundefinedbehavior).

Example2:Baseclasseswithoutpolymorphicdeletion.If

polymorphicdeletionshouldn'tbeallowed,thedestructor

mustbenonpublic(sothatcallingcodecan'tcallit)and

shouldbenonvirtual(becauseitneedn'tbevirtual).

Policyclassesarefrequentlyusedasbaseclassesfor

convenience,notforpolymorphicbehavior.Itisrecommended

tomaketheirdestructorsprotectedandnonvirtual.



Exceptions

Somecomponentarchitectures(e.g.,COMandCORBA)don't

useastandarddeletionmechanism,andfosterdifferent

protocolsforobjectdisposal.Followthelocalpatternsand

idioms,andadaptthisguidelineasappropriate.

Consideralsothisrarecase:

Bisbothabaseclassandaconcreteclassthatcanbe

instantiatedbyitself(andsothedestructormustbepublic

forBobjectstobecreatedanddestroyed).

YetBalsohasnovirtualfunctionsandisnotmeanttobe

usedpolymorphically(andsoalthoughthedestructoris

publicitdoesnotneedtobevirtual).

Then,eventhoughthedestructorhastobepublic,therecanbe

greatpressuretonotmakeitvirtualbecauseasthefirstvirtual

functionitwouldincuralltherun-timetypeoverheadwhenthe

addedfunctionalityshouldneverbeneeded.

Inthisrarecase,youcouldmakethedestructorpublicand

nonvirtualbutclearlydocumentthatfurther-derivedobjects

mustnotbeusedpolymorphicallyasB's.Thisiswhatwasdone

withstd::unary_function.

Ingeneral,however,avoidconcretebaseclasses(seeItem35).

Forexample,unary_functionisabundle-of-typedefsthatwas

neverintendedtobeinstantiatedstandalone.Itreallymakesno

sensetogiveitapublicdestructor;abetterdesignwouldbeto

followthisItem'sadviceandgiveitaprotectednonvirtual

destructor.



References

[Cargill92]pp.77-79,207[Cline99]Đ21.06,21.12-13

[Henricson97]pp.110-114[Koenig97]Chapters4,11

[Meyers97]Đ14[Stroustrup00]Đ12.4.2[Sutter02]Đ27

[Sutter04]Đ18



51.Destructors,deallocation,andswap

neverfail

Summary

Discussion

References



Summary

Everythingtheyattemptshallsucceed:Neverallowanerrorto

bereportedfromadestructor,aresourcedeallocationfunction

(e.g.,operatordelete),oraswapfunction.Specifically,types

whosedestructorsmaythrowanexceptionareflatlyforbidden

fromusewiththeC++standardlibrary.



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

Chapter 50.  Make base class destructors public and virtual, or protected and nonvirtual

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

×