Tải bản đầy đủ - 0 (trang)
Chapter 38.  Practice safe overriding

Chapter 38.  Practice safe overriding

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

Summary

Overrideresponsibly:Whenoverridingavirtualfunction,

preservesubstitutability;inparticular,observethefunction's

pre-andpost-conditionsinthebaseclass.Don'tchangedefault

argumentsofvirtualfunctions.Preferexplicitlyredeclaring

overridesasvirtual.Bewareofhidingoverloadsinthebase

class.



Discussion

Althoughderivedclassesusuallyaddmorestate(i.e.,data

members),theymodelsubsets,notsupersets,oftheirbase

classes.Incorrectinheritance,aderivedclassmodelsaspecial

caseofamoregeneralbaseconcept(seeItem37).

Thishasdirectconsequencesforcorrectoverriding:Respecting

theinclusionrelationshipimpliessubstitutabilityoperationsthat

applytoentiresetsshouldapplytoanyoftheirsubsetsaswell.

Afterthebaseclassguaranteesthepreconditionsand

postconditionsofanoperation,anyderivedclassmustrespect

thoseguarantees.Anoverridecanaskforlessandprovide

more,butitmustneverrequiremoreorpromiselessbecause

thatwouldbreakthecontractthatwaspromisedtocalling

code.

Definingaderivedoverridethatcanfail(e.g.,throwsan

exception;seeItem70)iscorrectonlyifthebaseclassdidnot

advertisethattheoperationalwayssucceeds.Forexample,say

EmployeeoffersavirtualmemberfunctionGetBuilding

intendedtoreturnanencodingofthebuildingwherethe

Employeeworks.WhatifwewanttowriteaRemoteContractor

derivedclassthatoverridesGetBuildingtosometimesthrow

anexceptionorreturnanullbuildingencoding?Thatisvalid

onlyifEmployee'sdocumentationspecifiesthatGetBuilding

mightfailandRemoteContractorreportsthefailureinan

Employee-documentedway.

Whenoverriding,neverchangedefaultarguments.Theyarenot

partofthefunction'ssignature,andclientcodewillunwittingly

passdifferentargumentstothefunction,dependingonwhat

nodeofthehierarchytheyhaveaccessto.Consider:

classBase{

//



virtualvoidFoo(intx=0);

};



classDerived:publicBase{

//

virtualvoidFoo(intx=1);//poorform,andsurpr

};

Derived*pD=newDerived;

pD->Foo();//invokespD->Foo(1)

Base*pB=pD;

pB->Foo();//invokespB->Foo(0)



Itcanbesurprisingtocallersthatthesameobject'smember

functionsilentlytakesdifferentargumentsdependingonthe

statictypetheyhappentoaccessitthrough.

Prefertoaddtheredundantvirtualwhenoverridinga

function.Itmakestheintentclearertothereader.

Bewareofinadvertentlyhidingoverloadsinthebaseclass.For

example:

classBase{//

virtualvoidFoo(int);

virtualvoidFoo(int,int);

voidFoo(int,int,int);

};



classDerived:publicBase{//

virtualvoidFoo(int);//overridesBase::Foo(int),but

};

Derivedd;

d.Foo(1);//ok



d.Foo(1,2);//error(oops?)

d.Foo(1,2,3);//error(oops?)



Ifthebaseclass'soverloadsshouldbevisible,writeausing

declarationtoredeclaretheminthederivedclass:



classDerived:publicBase{//

virtualvoidFoo(int);//overridesBase::Foo(int)

usingBase::Foo;//bringtheotherBase::Fooove

};



Examples

Example:Ostrich.IfclassBirddefinesthevirtualfunctionFly

andyouderiveanewclassOstrich(anotoriouslyflightless

bird)fromBird,howdoyouimplementOstrich::Fly?The

answeris,"Itdepends."IfBird::Flyguaranteessuccess(i.e.,

providestheno-failguarantee;seeItem71)becauseflyingis

anessentialpartoftheBirdmodel,thenOstrichisnotan

adequateimplementationofthatmodel.



References

[Dewhurst03]Đ73-74,Đ78-79[Sutter00]Đ21[Keffer95]p.

18



39.Considermakingvirtualfunctions

nonpublic,andpublicfunctions

nonvirtual

Summary

Discussion

Exceptions

References



Summary

Inbaseclasseswithahighcostofchange(particularlyonesin

librariesandframeworks):Prefertomakepublicfunctions

nonvirtual.Prefertomakevirtualfunctionsprivate,orprotected

ifderivedclassesneedtobeabletocallthebaseversions.

(Notethatthisadvicedoesnotapplytodestructors;seeItem

50.)



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

Chapter 38.  Practice safe overriding

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

×