C++ 物件导向程序设计100_第1页
C++ 物件导向程序设计100_第2页
C++ 物件导向程序设计100_第3页
C++ 物件导向程序设计100_第4页
C++ 物件导向程序设计100_第5页
已阅读5页,还剩107页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1C++物件导向程序设计

IntroductiontoC++withOOP2AgendaFromCtoC++(C++==abetterC+Objec-Orientedsupport)

a.I/Ostream,b.pass-by-referencec.functionnameoverloading,

d.operatoroverloading,e.defaultparameter,f.inlinefunction,g.templatefunctionDataAbstraction:Whyusingstruct?Whyusingclass?AnADTexample:Howtodesign/construct/useaStack?nexttopic: IntroductiontoOOA,OOD,andUML3FromCtoC++C++最重要的当然是class(类别)C++除了class外还有一些雕虫小技I/OstreamfacilityandotherClassLibraryParameterpassing?(C++可指定callbyreference)functionnameoverloading(函数名称重复使用)Operatoroverloading,…

n=5+38;x=25.8+3.69;inlinefunction?(只影响编译与执行效率,不影响答案)templatefunction,templateclass,…4C++Input/OutputStreamInC,fscanf(stddin,…);fprintf(stdout,…);fprintf(stderr,…);

printf("Enternewyy:");/*whereyyisafloat*/

scanf("%f",

&yy);/*whatifyyisadouble?

*/

printf("Thenewyyis:%f\n",yy);InC++,I/Odevices用起来像Object(物件)cout<<"Enternewyy:";

cin>>yy;

cout<<"Thenewyyis:"<<yy<<endl;read(0,…);write(1,…);write(2,…);/*systemcall*/InJava,System.out.print("Theansweris"+ans+"\n");5CandC++I/OcomparedC-styleI/O:Notypesafety.Whathappenswithprintf(“%d”,‘c’);?Conversionspecificationshaveahighlearningcurve.AlmostallthestateoftheI/Oiscontainedinthefunctioncall.C++styleI/O:Manipulatorsareveryverbose/annoyingGlobalstategetschanged.Whenyoudo“cout<<2.4555”,whatprecisionareyousetat?Youdon’tknow.YougetmorecustomizabilitysinceC++I/Oisclassedbased.NEVERmixCandC++I/O...untilyouknowwhatios::sync_with_stdio()does.6Pass-By-ReferenceAreferenceparameterinafunction"references"thesamephysicalmemorylocationastheargumentpassedinChangingthevalueofareferenceparameter:DoesnotchangethememoryassociatedwiththeparameterDoeschangethememoryassociatedwiththeargumentpassedinTherefore–argument'smemorymustnotbeconstantorliteralvoidrefFunc(float&val){

val=50;}intmain(){intmainVal=9;refFunc(mainVal);cout<<"mainVal:"<<mainVal<<endl;return(0);}mainVal:50Thisassignmentchangesthememoryassociatedwiththisvariable!7参数传递(parameterpassing)

/*写一个函数可以将传入的两整数参数对调*//*函数如何写?*/return_typefunction_name(parameters){localvariables;statements;}/*如何叫用?*/function_name(actualarguments);?C语言参数是passbyvalueC++语言参数则可以passbyReference不过,这违反了C的设计者所谓的“怎么宣告就怎么用”;例如:看到int*x;所以*x就当int来用!而x则是int*;就是说x是一个指向整数的指标!8参数(parameter)传递/*写一个函数可以将两整数对调,wrongversion*/#include<stdio.h>voidswap(intx,inty){inttemp;temp=x;x=y;y=temp;}intm=38,n=49;intmain(){

swap(m,n);/*没有用的!

回来后m,n不变*/printf("m=%d,n=%d\n",m,n);}(错)因为C语言参数是passbyvalue(错)(错)(错)9参数会被函式改变的传递法/*写一个函数可以将两整数对调,correctversion*/#include<stdio.h>voidswap(int*x,int*y){/*注意参数写法*/inttemp;

temp=*x;

*x=*y;

*y=temp;}/*注:C++则有passbyreference写法

*/intm=38,n=49;intmain(){

swap(&m,&n);/*注意&m和&n把address传过去*/printf("m=%d,n=%d\n",m,n);}(正确)参考K&R课本5.2节注意不要在temp左边写星号,意思不同&m,&n:addressofm和addressofnCallbyaddresstopointer10CallbyReference参数传递/*写一个函数可以将两整数对调,inC++*/#include<stdio.h>voidswap(int&x,int&y){inttemp;temp=x;x=y;y=temp;}intm=38,n=49;intmain(){swap(m,n);/*注意!

看起来好像不会变*/printf("m=%d,n=%d\n",m,n);}(C++专有)C++才可以用passbyReference前面所说的Clanguage可用之方法仍可以用于C++.11FunctionnameOverloading/*写个函数可将两int数对调,再写一个函数可以将两double数对调,名称?

*/#include<stdio.h>voidswap(int&x,int&y){/*byreference*/inttemp;temp=x;x=y;y=temp;}voidswap(double&x,double&y){doubletemp;temp=x;x=y;y=temp;}(C++专有)C++允许同名的function,但注意参数12C++STL中的swap()是templatetemplate<classT>voidswap(T&x,T&y){Ttemp;temp=x;x=y;y=temp;}此即所谓的templatefunction(样版函数)STL=StandardTemplateLibrary13再谈functionnameoverloadingFunctionnameoverloading不一定在class内!请注意它与ObjectOriented并没有关系!functionnameoverloading是指很多个函数都用同一个名称例如: intm=2,n=3; doublex=3.8,y=4.9; swap(m,n); swap(x,y);

显然以上两个swap应该是不同函数,这是由它们的参数不同得知的!这在compiletime就可以决定是用哪一个swap,此称之为staticbinding(静态系结)!如何做?(nextslide)?何谓dynamicbinding?(nextslide)C++允许同名的function,但注意参数14C++Howto…overloading/polymorphismC++到底是用了什么技术办到functionnameoverloading?

事实上只是用了一个超级简单的idea:C++只是把参数的型别纳入函数名称中而已,Compiler会偷换functionname,参数的type也变成function_name的一部份:(

staticbinding)

例如:voidswap(int&,int&);会被译为(可能!): __swap_F2RiRi如何达成polymorphism?透过virtualfunction

dynamicbinding

p->draw();译成去执行p指过去之物件内有个指标指过去的函数表中draw的项目位置指过去的那个函数!(相关指标在new出物件时填入)15TipsaboutDynamicbindingDynamicbinding(动态系结)是指在执行阶段(runtime)才确定!动态系结是一种被Compiler使用的技术,它也不是OO才有的,C语言的Auto变量(函数中没有宣告static的Local变量)就是使用Dynamicbinding;在执行期(Runtime)时才安排于堆栈(Stack)中!Staticbinding?vs.Dynamicbinding?16Operatoroverloading(1/4)Operatoroverloading

Usetraditionaloperatorswithuser-definedobjectsAstraightforwardandnaturalwaytoextendC++Requiresgreatcare

Whenoverloadingmisused,programdifficulttounderstandFormatoftheoperatorfunctionFunctionnameiskeywordoperatorfollowedbythesymbolfortheoperatorbeingoverloaded.

operator+wouldbeusedtooverloadtheadditionoperator(+)17Operatoroverloading(2/4)YoucanNOTinventoperatorNonewoperatorscanbecreated,useonlyexistingoperatorsArity(numberofoperands)canNotbechangedUnaryoperatorsremainunary,andbinaryoperatorsremainbinaryOperators&,*,+and-eachhaveunaryandbinaryversionsUnaryandbinaryversionscanbeoverloadedseparatelyCanNOToverloadoperatorsforBuilt-intypesYoucannotchangehowtwointegersareadded18Operatoroverloading(3/4)OperatorfunctionsCanbememberornon-memberfunctions(i.e.,friend)Operatorfunctionsfortheassignmentoperatorsmustbeamemberfunctioni.e:(),[],->,=Memberfunctionvs.non-memberfunctionLeftmostoperandmustbeanobject(orreferencetoanobject)oftheclassIfleftoperandofadifferenttype,operatorfunctionmustbeanon-memberfunctionAnon-memberoperatorfunctionmustbeafriendifprivateorprotectedmembersofthatclassareaccesseddirectly19Operatoroverloading(4/4)OverloadedbinaryoperatorsNon-staticmemberfunction,oneargumentNon-memberfunction,twoargumentsLeftmostoperandmustbeanobject(orreferencetoanobject)oftheclassIfleftoperandisanobjectofadifferenttype,operatorfunctionmustbeanon-memberoperatorfunctionAnon-memberoperatorfunctionmustbeafriendifprivateorprotectedmembersofthatclassareaccesseddirectly20OperatorsinC/C++/Java(1/3):OperatorCC++JavaScoperes.::Memberselection,subscripting,functioncall,sizeof.->[]().->[]()sizeofn/an/a[]()n/aUnaryops,address,dereference,cast,allocate,deallocate-!++--&*()n/an/a-!++--&*()newdelete-!++--n/an/a()n/an/aMultiply,divide,mod*/%*/%*/%Add,subtract+-+-+-Shift<<>><<>><<>>21OperatorsinC/C++/Java(2/3):OperatorCC++Javarelational<<=>>=<<=>>=<<=>>=equality==!===!===!=bitwiseAND&&&bitwiseXOR^^^bitwiseOR|||logicalAND&&&&&&logicalOR||||||22OperatorsinC/C++/Java(3/3):OperatorCC++Javaconditional?:?:?:assignment=*=/=%=+=-=<<=>>=&=!=^==*=/=%=+=-=<<=>>=&=!=^==*=/=%=+=-=<<=>>=&=!=^=exceptionthrow

sequencing,,,23OperatorOverloadingExamples(1/3)Asamemberfunction(写成自己人)classHaha{

public:

constHaha&operator+=(constHaha&p)const{/***mutablemember是例外***/}

//...

};Hahax,y,z;//…//then: y+=z; //equivalentto

y.operator+=(

z

);//operator+=isamember表示不会改

memberdata,此例显然不该写这个const,Why?24OperatorOverloadingExamples(2/3)Asfriendfunction(不好,但文法正确)classHaha{

public:

friendconstHaha&operator+=(Haha&,constHaha&);//...

};constHaha&operator+=(Haha&x,constHaha&y){/*…*/}Hahax,y,z;//…//then: y+=z; //equivalentto

operator+=(

y,z

);//operator+=isafriendoperator+=

应写成自己人比较好25OperatorOverloadingExamples(3/3)Asfriendfunctionagain(可以,很好)classHaha{longdata_;public:

friendostream&operator<<(ostream&,constHaha&);//...

};ostream&operator<<(ostream&river,constHaha&y){river<<y.data_;/*…*/}Hahax;//…//then:cout<<x; //equivalentto

operator<<(

cout,x);//operator<<isafriendOperator<<

一定要写成朋友!无法写成自己人!Why?26DefaultparametervoidsetNum(intx=3388);voidsetNum(intx){cout<<"Yougaveme"<<x<<endl;//…}setNum(123);setNum();/*compiler会自动填入3388*/setNum(456);27inlineFunctionsInlinefunctionisanimportantadditiontoC++becauseitcanallowyoutocreateveryefficientcode.Theyareespeciallyimportantinclasses,becausealotoffunctions,suchastheconstructororaccessorsareexecutedveryoften.Inlineisactuallyjustarequesttothecompiler,notacommand.(eg.recursivefunctionsoftennotsetinline)inlinefunctions=fasterprocessing–largercodesize

写了inline的函数,用到时用展开的(类似macro),不是译成呼叫;在class内就写完的function会自动变inlinefunction;在class之外写的function要写明inline才是inlinefunction.(C99也可用)只要在原来function之前面写inline,就可能使得function变成inlinefunction.这是要求Compiler采用类似Macro(巨集)展开方式来翻译该函数呼叫!所以通常机器码较占空间,但执行起来比较快(用空间换时间);但是它仍然具有function的效果!注意:含有某些statements的functions无法成为inline,compiler会把关!28templatefunctiontemplate<classT>voidswap(T&x,T&y){Ttemp;temp=x;x=y;y=temp;}inta=38,b=49,m=123,n=456;doublex=23.5,y=33.88;swap(a,b);/*会生出一份swapfunction*/swap(x,y);swap(m,n);/*不会再生出一份function*/swap()inSTL(StandardTemplateLibrary)29再谈变量Variable变变变变量当然会变才叫变量

–废话!变量命名规则与惯例?averageScore,

n,x变量放在计算机的存储器–何处?与程序一起,与程序分离?–由Linker负责堆栈区(STACK)?

嘿洗虾密碗糕啊?变量的能见范围(Scope)?或说有效范围函数(函式)内的变量:Localvariable局部(区域)变量函数外的变量:Globalvariable整体变量变量何时生出?何时死掉?生命期

(Lifetime)?30变量分类依能见范围(Scope,或说有效范围)?Local区域vs.Global整体依何时给它存储器位置

(称作binding)Staticvariable:静态变量,Run之前(compile/Link)Dynamicvariable:动态变量,Run之后才会做binding(就是Run之后才给它位置)自动要自动还:auto变量(function内没写static)手动要:

使用malloc或calloc要,用free还(C++用new和delete)auto

变量被安排在stack(堆栈)手动要的(malloc,calloc)在Heap(堆积)31变量(Variable)

的Scope,Lifetime变量的能见范围(Scope,或说有效范围)函数(函式)内的变量:Localvariable局部(区域)变量:只有在函数内有效函数外的变量:Globalvariable(整体变量)Globalvariable:宣告之后就一直有效变量生命期

(Lifetime)?静态变量从程序开始Run就“出生”Auto变量在进入函数时生出,离开函数时死掉(把存储器还给系统)没有宣告static的:Local变量就是Auto变量32Global变量vs.Local变量#include<iostream.h>intx=38,y=250;/*Global*/voidsub1(int);/*见后面程序*/intmain(){intx=49;/*Local*/sub1(::x);/*Global的x==38*/sub1(x);/*Local的x==49*/

cout<<"x="<<x<<endl;cout<<"outsidex="<<::x<<endl;cout<<"y="<<y<<endl;return0;/*0inmain()meansOK*/}(1/2)33Global变量vs.Local变量voidsub1(inty){cout<<"y="<<y<<endl;x++;/*Global的x,因为Local没有x*/::x++;/*也是Global的x*/y++;/*因为y是passbyvalue,回去不会变*/::y++;/*是Global的y*/return;/*不写也可以*/}(2/2)passbyvalue就是callbyvalue讲法不同而已

34StaticLocal变量#include<iostream.h>//#include<iostream>intfa(){intx=1;

returnx++;/*先取其值,再做++*/}intfb(){

static

intx=1;/*

注意staticintx=1;*/

returnx++;}intmain(){cout<<"fa()="<<fa()<<fa()<<fa()<<endl;cout<<"fb()="<<fb()<<fb()<<fb()<<endl;return0;/*0inmain()meansOK*/}returnx++;和

return++x;

不同

!(1/2)35StaticLocal变量intfa(){intx=1;returnx++;/*先取其值,再做++*/}intfb(){

static//把static写在下列左方也一样

intx=1;//注意staticintx=1;returnx++;

}(2/2)36StaticLocal变量,evaluation顺序#include<stdio.h>intfa();/*宣告*/intfb();intmain(){/*不同系统可能不同答案*/printf("fa()=%d%d%d\n", fa(),fa(),fa());printf("fb()=%d%d%d\n", fb(),fb(),fb());return0;/*0inmain()meansOK*/}//intfa()…

也可以写在另一个档案内37Evaluation顺序#include<stdio.h>intgg(intx){staticans=0;ans=x+ans*ans;returnans;}intmain(){/*不同系统可能不同答案!*/inthaha=gg(1)+gg(2)+gg(3);/*先做哪个gg()?*/printf("haha=%d\n",haha);return0;}

expression中有多个函数叫用会先做哪个gg()?C/C++没有规定!所以看写compiler的人高兴

38Auto变量不可占太多memoryAuto变量就是没写static

的Local变量Auto变量是在进入函数时才在STACK区安排存储器,

在离开函数(return)时就还掉(改变StackPointer)STACK区一般不会很大(几十KBytes)Auto变量用STACK区,所以太大的array不能用叫用函数时,returnaddress也会被推入

STACK

参数传递也是用STACK区

C/C++推入参数时是先推入最后一个参数,这使得第一个参数会在堆栈的最上方,进入函数时,STACK中

returnaddress之下就是第一个参数

C/C++离开函数时,函数不负责拿掉STACK中

的参数,那是叫用函数那个程序的责任!(与其它语言不同)39Auto变量占用STACK区memoryAuto变量就是没写static

的Local变量CPUIPSPInstructionPointerStackPointer系统区系统区程序+静态dataHEAP堆积malloc(),new()STACK(参数与Auto变量)Heap由上往下长Stack由下往上长address040Static变量?Global变量都是static

的变量Local变量就是写在函数内的变量有补static修饰词则为static变量(静态变量)没有补static修饰词则为Auto变量(自动变量)static

的变量在程序开始RUN之前就存在,且已经设好初值,程序结束后才会还掉所占存储器(生命期)写了extern表示只是宣告(declare),不是定义(define)Local变量就只能在该函数(function)内存取(access)Global变量则只要看得见它的任一函数都能存取它宣告之后就看得见,没宣告就定义则看作同时宣告了注意main()也是函数,没有特别伟大!应写成intfunction.41Global,StaticLocal,Auto变量#include<stdio.h>

externintx;/*只有宣告,还不知道位置在何处?*/intfa();intfb(){intans=0;return++ans;}intmain(){intkk=123;cout<<"fa()="<<fa()<<fa()<<fa()<<kk<<endl;cout<<"fb()="<<fb()<<fb()<<fb()<<endl;return0;/*0inmain()meansOK*/}intx,y;/*真的x在这,也可以写在另一个file中*/intfa(){/*…*}写了extern表示只是宣告,不是定义(define)42StaticGlobal变量#include<stdio.h>#defineBUFSIZE100

staticcharbuf[BUFSIZE];

staticintbufp=0;intgetch(){/*...*/}voidungetch(intc){/*...*/}InformationHiding?也参考stack的push和pop写在同一独立file中,push和pop共享dataFunctionsinanotherfilecanNOTseethesestatic

variable43再谈StaticGlobal变量#include<stdio.h>#defineRAND_MAX65535

staticunsignedlongseed=0;/*global*/intrand(){

seed=seed*1103515245+12345;returnseed%(RAND_MAX+1);}voidsrand(intnewseed){

seed=newseed;}

程序库中的PseudoRandomNumberGenerator(PRNG)InformationHiding?只有rand和srand看得见seed44register变量,volatile变量#include<stdio.h>enum{BUFSIZE=100,NSTU=60};

registerintwrong;/*thisiswrong,global不可*/volatileinthaha;voidmyfun(registerintx){

registerintyy,i;/*OK*/int*p;/*...*/p=&yy;/*thisiswrong*/}参考K&R课本4.7节拜托Compiler尽可能安排在CPU内的暂存器45volatile变量#include<stdio.h>volatileinthaha;/*tellcompiler…*/intmain(){intk;doubleans;for(k=1;k<=99;++k){/*...*/ans=haha*haha;/*doNOToptimize*/printf("ans=%f\n",ans);}}参考K&R课本4.7节警告Compiler这变量可能会被别的程序改变46AnAbstractDataType(ADT)isauser-defined

datatypethatsatisfiesthefollowingtwoconditions:(Encapsulation+

InformationHiding)Therepresentationof,andoperationson,objectsofthetypearedefinedinasinglesyntacticunit;also,otherprogramunitscancreateobjectsofthetype.Therepresentationofobjectsofthetypeishiddenfromtheprogramunitsthatusetheseobjects,sotheonlyoperations(methods)possiblearethoseprovidedinthetype'sdefinitionwhichareknownasinterfaces.ADT---DataAbstraction47ADTinC_plus_plusclass/structcanbeusedastheencapsulationdevice.(只有一开始defaultaccess属性不同)Alloftheclassinstancesofaclassshareasinglecopyofthememberfunctions.Eachinstanceofaclasshasitsowncopyoftheclassdatamembers(exceptstaticdata)Instancescanbestatic,stackdynamic(auto),orheapdynamic;thisissimilartobuilt-intypes.classinstanceofaclass=ObjectObjectisaninstanceofsomeclass48C++=abetterC+classes

WhyusingstructinC?Grouprelateddatatogether(后面讲)C++最重要的就是class(类别)class其实是struct

的延伸InC++,wecanputrelated

functionswiththerelated

datainstruct(class)所以C++的class

就是C的struct

加上一些规定Java把struct拿掉了!且union也没了!class

有何用?(后面讲)49ObjectOrientedConcept(1/3)Whyusingclass?(先考虑whyusingstruct?)支援OOP(物件导向ObjectOrientedProgramming)

又译作

个体导向程序设计考虑Stack堆栈:让东西用起来更像东西ADT(AbstractDataType)把data以及对该些data有关的方法(method)或称函数(function,函式)封装(encapsulate)在一个程序单元方便使用50ObjectOrientedConcept(2/3)Object-OrientedAnalysis(OOA)Goal:UnderstandthedomainObject-OrientedDesign(OOD)Goal:Designasolution,amodelofthedomaininwhichthedesiredactivitiesoccurObject-OrientedProgramming(OOP)Goal:ImplementthesolutionNote:AGoodDesignis2/3BeforeYouHittheKeyboard51ObjectOrientedConcept(3/3)//如何让Stack(堆栈)用起来更像在使用物件

//或者说像在使用零件(Component,软件IC)intmain(){Stackxo;/*xoisanobject,itisaStack*/xo.push(880);/*要求xo把880push进去*/xo.push(770);xo.push(53);

while(!xo.isempty()){cout<<""<<xo.pop();/*要求xo吐出顶端元素*//*......*/

}cout<<endl;return0;}How?如何制作Stack?52TakeaBreak(12min.)不要跑掉tsaiwn@.tw蔡文能Whyusingstruct?53问题与思考(如何自定资料结构?)

Whyusingstruct?只能用char,int,float,double等这些datatype吗?Userdefineddatatype?考虑写程序处理全班成绩资料,包括加总平均并排序(Sort)然后印出一份照名次排序的全部资料以及一份照学号排序的全班资料如何做Sort(排序)?Sort时两学生资料要對調,要如何对调?有很多array?存学号的array,存姓名的array?存成绩的array?…

万一忘了一个array?Bubblesort,Insertionsort,Selectionsort54So,Whyusingstruct?struct可以把相关资料group在一起structStudentx[99],tmp;/*…*/tmp=x[i];x[i]=x[k];x[k]=tmp;增加程序可读性程序更容易维护structStudent{longsid;charname[9];/*…*/};/*注意“;”分号*/structStudentyy;C++与C99可以不写“struct”这字;C须用typedef55C须用typedef才可不写structtypedefstructStudent{longsid;charname[9];/*…*/}Student_t;/*注意“;”分号*/structStudentyy;Student_tstemp;//stemp也是Student一般建议:user-defineddatatype用大写字母开头!56WhatisObject?Class?(1/2)object就是“东西”,就是以前的“变量”class就是“类别”,某种东西的型别intm,n;/*int是整数类别

*//*m,n都是变量*/Studentx,y;/*Student是我们自订类别

*//*x,y都是object*/57WhatisObject?Class?(2/2)objectisaninstanceofsomeclass文法上,C++的class就是以前的structclassStudent{public:/*…与写struct同*/};structNode{private:/*…与写class同*/};58Class与struct文法上?classStudent{//private:longsid;charname[9];};Studentx,y[99],tempstu;不可以使用x.sid等等Why??InformationhidingstructStudent{longsid;charname[9];};Studentx,y[99],tempstu;可以使用x.sidy[3].sid=tempstu.sid;59

用array来做STACK(1/2)

sptrStackPointerintsptr;01-1intx[99];voidpush(inty){

++sptr;x[sptr]=y;}intans=pop();Initialization:sptr=-1;/*empty*/需要一个array和一个整数push(456);

push(3388);

4563388intpop(){

inttmp=x[sptr];--sptr;returntmp;}9860用array来做STACK(2/2)

staticintx[99];/*别的档案看不到这*/

staticintsptr=-1;/*emptystack*/voidpush(inty){++sptr;/*movestackpointer*/x[sptr]=y;/*putthedataythere*/}intpop(){returnx[sptr--];/*注意

--写后面*/}/*其它相关function例如isempty()*/61使用STACK

externvoidpush(int);/*宣告*/

externintpop();#include<stdio.h>intmain(){push(543);push(881);printf("%d\n",pop());}/*可以用!但若要两个Stack呢?*/62MoreaboutSTACK(1/3)/*若要两个Stack呢?*/解法之一==>使用两个array,并把array

当参数

push(ary2,x);ans=top(ary2);

但是这样该些array

必须开放让使用者知道

要让宣告extern就看得到,不可再用staticGlobal

违反不必让使用者知道push到哪去的Information Hiding原则!

(或是该些

array

要定义在使用者程序里面,更不好!)63MoreaboutSTACK(2/3)/*若要两个Stack呢?*/解法之二(better,butNOTgoodenough!)==>整个档案复制到另一个file,并把各相 关函数名称都改掉,例如push2, pop2,…==>array

与变量名称都不用改!Why? (因为

static

Global

使其它file中function看不见)但是这样也不是很方便,函数名称一大堆

若要三个Stack呢?四个呢?…

(不过这比前面使用不同array

的方法好!)64MoreaboutSTACK(3/3)/*若要两个Stack呢?*//*若要三个Stack呢?四个?五个...*//*有没有更方便直接的方法?*/

solution==>usingC++Class todefine

aStackasaSoftwareComponent (软件元件或零件)Stackx;Stacky;x.push(13579);y.push(258);y.push(x.pop());65Stack--classexample(1/2)mystk.hclassStack{//private:longdata[99];/*直接写99

不是好习惯*/intsptr;public:Stack();/*constructor*/voidpush(long);longpop();

boolisempty();};/*classStack*/

bool要新版的C++才有,如果不能用就改用int标准程序库的堆栈是stack

注意是小写!且其pop()是void标准程序库是empty66Stack--classexample(2/2)mystk.cpp#include"mystk.h"#include<iostream.h>

Stack::Stack(){sptr=-1;}/*Constructor*/voidStack::push(longxx){/*注意Stack::*/data[++sptr]=xx;}longStack::pop(){returndata[sptr--];}

boolStack::isempty(){returnsptr==-1;}//...bool要新版的C++才有这是实作出Stack,前面mystk.h只是宣告Initialization工作要写在特殊函数67使用Stack--File:mymain.cpp#include"mystk.h"#include<iostream.h>intmain(){Stackxo,brandy;xo.push(880);xo.push(770);xo.push(53);

while(!xo.isempty()){cout<<""<<xo.pop();

}cout<<endl;return0;}//新写法#include<iostream>usingnamespacestd;68如何执行前述Stack程序?#include"mystk.h"#include<iostream>usingnamespacestd;intmain(){Stackxo,brandy;xo.push(880);xo.push(770);xo.push(53);

while(!xo.isempty()){cout<<""<<xo.pop();

}cout<<endl;/*newLine*/return0;}53770880gccmymain.cppmystk.cpp./a.outgcc–cmystk.cppgccmymain.cppmystk.o./a.out//OR69Stack(使用)可全写在一file,但??classStack{//private:longdata[99];/*直接写99

不是好习惯*/intsptr;public:Stack(){sptr=-1;};voidpush(longxx){data[++sptr]=xx;}longpop(){returndata[sptr--];}

boolisempty(){returnsptr==-1;}

};

#include<iostream.h>intmain(){Stackxo,brandy;xo.push(880);xo.push(770);xo.push(53);

while(!xo.isempty()){cout<<""<<xo.pop();

}cout<<endl;return0;}坏处:

若要

reuseStack呢?

切下来另存档案?

不方便!不符合OOP原则这样这些会变

inlinefunction70class内要用enum生出常数/***g++thisfile.cpp;./a.out***/#include<iostream>usingnamespacestd;#include<stdio.h>classStack{//private:

public:enum{size=99};/*正确的好习惯*/

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论