Giao Trinh OOP

You might also like

Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 393

CHNG 1

GII THIU V LP TRNH HNG I TNG


1.1 LP TRNH HNG I TNG (OOP) L G ?
Lp trnh hng i tng (Object-Oriented Programming, vit tt l OOP) l mt phng php mi trn bc ng tin ha ca vic lp trnh my tnh, nhm lm cho chng trnh tr nn linh hot, tin cy v d pht trin. Tuy nhin hiu c OOP l g, chng ta hy bt u t lch s ca qu trnh lp trnh xem xt OOP tin ha nh th no. 1.1.1 Lp trnh tuyn tnh

My tnh u tin c lp trnh bng m nh phn, s dng cc cng tt c kh np chng trnh. Cng vi s xut hin ca cc thit b lu tr ln v b nh my tnh c dung lng ln nn cc ngn ng lp trnh cp cao u tin c a vo s dng . Thay v phi suy ngh trn mt dy cc bit v byte, lp trnh vin c th vit mt lot lnh gn vi ting Anh v sau chng trnh dch thnh ngn ng my. Cc ngn ng lp trnh cp cao u tin c thit k lp cc chng trnh lm cc cng vic tng i n gin nh tnh ton. Cc chng trnh ban u ch yu lin quan n tnh ton v khng i hi g nhiu ngn ng lp trnh. Hn na phn ln cc chng trnh ny tng i ngn, thng t hn 100 dng. Khi kh nng ca my tnh tng ln th kh nng trin khai cc chng trnh phc tp hn cng 1

tng ln. Cc ngn ng lp trnh ngy trc khng cn thch hp i vi vic lp trnh i hi cao hn. Cc phng tin cn thit s dng li cc phn m chng trnh vit hu nh khng c trong ngn ng lp trnh tuyn tnh. Tht ra, mt on lnh thng phi c chp lp li mi khi chng ta dng trong nhiu chng trnh do chng trnh di dng, logic ca chng trnh kh hiu. Chng trnh c iu khin nhy n nhiu ch m thng khng c s gii thch r rng, lm th no chng trnh n ch cn thit hoc ti sao nh vy. Ngn ng lp trnh tuyn tnh khng c kh nng kim sot phm vi nhn thy ca cc d liu. Mi d liu trong chng trnh u l d liu ton cc ngha l chng c th b sa i bt k phn no ca chng trnh. Vic d tm cc thay i khng mong mun ca cc phn t d liu trong mt dy m lnh di v vng vo tng lm cho cc lp trnh vin rt mt thi gian. 1.1.2 Lp trnh cu trc: R rng l cc ngn ng mi vi cc tnh nng mi cn phi c pht trin c th to ra cc ng dng tinh vi hn. Vo cui cc nm trong 1960 v 1970, ngn ng lp trnh c cu trc ra i. Cc chng trnh c cu trc c t chc theo cc cng vic m chng thc hin. V bn cht, chng trnh chia nh thnh cc chng trnh con ring r (cn gi l hm hay th tc) thc hin cc cng vic ri rc trong qu trnh ln hn, phc tp hn. Cc hm ny c gi cng c lp vi nhau cng nhiu cng tt, mi hm c d liu v logic ring.Thng tin c chuyn giao gia cc hm thng qua cc tham s, cc hm c th c cc bin cc b m khng mt ai nm bn ngoi phm vi ca hm li c th truy xut c chng. Nh vy, cc hm c th c xem l cc chng trnh con c t chung vi nhau xy dng nn mt ng dng. Mc tiu l lm sao cho vic trin khai cc phn mm d dng hn i vi cc lp trnh vin m vn ci thin c tnh tin cy v d bo qun chng trnh. Mt chng trnh c cu trc c hnh thnh bng cch b gy cc chc nng c bn ca chng trnh thnh cc mnh nh m sau tr thnh cc hm. Bng cch c lp cc cng vic vo trong cc hm, chng trnh c cu trc c th lm gim kh nng ca mt hm ny nh hng n mt hm khc. Vic ny cng lm cho vic tch cc vn tr nn d dng hn. S gi gn ny cho php chng ta c th vit cc chng trnh sng sa hn v gi c iu khin trn tng hm. Cc bin ton cc khng cn na v c thay th bng cc tham s v bin cc b c phm vi nh hn v d kim sot hn. Cch t chc tt hn ny ni ln rng chng ta c kh nng qun l logic ca cu trc chng trnh, lm cho vic trin khai v bo dng chng trnh nhanh hn v hu hin hn v hiu qu hn. Mt khi nim ln c a ra trong lp trnh c cu trc l s tru tng ha (Abstraction). S tru tng ha c th xem nh kh nng quan st mt s vic m khng cn xem xt n cc chi tit bn trong ca n. Trong mt chng trnh c cu trc, chng ta ch cn bit mt hm cho c th lm c mt cng vic c th g l . Cn lm th no m cng vic li thc hin c l khng quan trng, chng no hm cn tin cy c th cn c th dng n m khng cn phi bit n thc hin ng n chc nng ca mnh nh th no. iu ny gi l s tru tng ha theo chc nng (Functional abstraction) v l nn tng ca lp trnh c cu trc. Ngy nay, cc k thut thit k v lp trnh c cu trc c s rng ri. Gn nh mi ngn ng lp trnh u c cc phng tin cn thit cho php lp trnh c cu trc. Chng trnh c cu trc d vit, d bo dng hn cc chng trnh khng cu trc. S nng cp nh vy cho cc kiu d liu trong cc ng dng m cc lp trnh vin ang vit cng ang tip tc din ra. Khi phc tp ca mt chng trnh tng ln, s ph thuc ca n vo cc kiu d liu c bn m n x l cng tng theo. Vn tr r rng l cu trc d liu trong chng trnh quan trng chng km g cc php ton thc hin trn chng. iu ny cng tr r rng hn khi kch thc ca chng trnh cng tng. Cc kiu d liu c x l trong nhiu hm khc nhau bn trong mt chng trnh c cu trc. Khi c s thay i trong cc d liu ny th cng cn phi thc hin c cc thay i mi ni c cc thao tc tc ng trn chng. y c th l mt cng vic tn thi gian v km hiu qu i vi cc chng trnh c hng ngn dng lnh v hng trm hm tr ln. Mt yu im na ca vic lp trnh c cu trc l khi c nhiu lp trnh vin lm vic theo nhm cng 2

mt ng dng no . Trong mt chng trnh c cu trc, cc lp trnh vin c phn cng vit mt tp hp cc hm v cc kiu d liu. V c nhiu lp trnh vin khc nhau qun l cc hm ring, c lin quan n cc kiu d liu dng chung nn cc thay i m lp trnh vin to ra trn mt phn t d liu s lm nh hng n cng vic ca tt c cc ngi cn li trong nhm. Mc d trong bi cnh lm vic theo nhm, vic vit cc chng trnh c cu trc th d dng hn nhng sai st trong vic trao i thng tin gia cc thnh vin trong nhm c th dn ti hu qu l mt rt nhiu thi gian sa cha chng trnh. 1.1.3 S tru tng ha d liu: S tru tng ha d liu (Data abstraction) tc ng trn cc d liu cng tng t nh s tru tng ha theo chc nng. Khi c tru tng ha d liu, cc cu trc d liu v cc phn t c th c s dng m khng cn bn tm n cc chi tit c th. Chng hn nh cc s du chm ng c tru tng ha trong tt c cc ngn ng lp trnh, Chng ta khng cn quan tm cch biu din nh phn chnh xc no cho s du chm ng khi gn mt gi tr, cng khng cn bit tnh bt thng ca php nhn nh phn khi nhn cc gi tr du chm ng. iu quan trng l cc s du chm ng hot ng ng n v hiu c. S tru tng ha d liu gip chng ta khng phi bn tm v cc chi tit khng cn thit. Nu lp trnh vin phi hiu bit v tt c cc kha cnh ca vn , mi lc v v tt c cc hm ca chng trnh th ch t hm mi c vit ra, may mn thay tru tng ha theo d liu tn ti sn trong mi ngn ng lp trnh i vi cc d liu phc tp nh s du chm ng. Tuy nhin ch mi gn y, ngi ta mi pht trin cc ngn ng cho php chng ta nh ngha cc kiu d liu tru tng ring. 1.1.4 Lp trnh hng i tng: Khi nim hng i tng c xy dng trn nn tng ca khi nim lp trnh c cu trc v s tru tng ha d liu. S thay i cn bn ch, mt chng trnh hng i tng c thit k xoay quanh d liu m chng ta c th lm vic trn , hn l theo bn thn chc nng ca chng trnh. iu ny hon ton t nhin mt khi chng ta hiu rng mc tiu ca chng trnh l x l d liu. Suy cho cng, cng vic m my tnh thc hin vn thng c gi l x l d liu. D liu v thao tc lin kt vi nhau mt mc c bn (cn c th gi l mc thp), mi th u i hi th kia c mc tiu c th, cc chng trnh hng i tng lm tng minh mi quan h ny. Lp trnh hng i tng lin kt cu trc d liu vi cc thao tc, theo cch m tt c thng ngh v th gii quanh mnh. Chng ta thng gn mt s cc hot ng c th vi mt loi hot ng no v t cc gi thit ca mnh trn cc quan h . V d1.1: Chng ta bit rng mt chic xe c cc bnh xe, di chuyn c v c th i hng ca n bng cch quo tay li. Tng t nh th, mt ci cy l mt loi thc vt c thn g v l. Mt chic xe khng phi l mt ci cy, m ci cy khng phi l mt chic xe, chng ta c th gi thit rng ci m chng ta c th lm c vi mt chic xe th khng th lm c vi mt ci cy. Chng hn, tht l v ngha khi mun li mt ci cy, cn chic xe th li chng ln thm c khi chng ta ti nc cho n. Lp trnh hng i tng cho php chng ta s dng cc qu trnh suy ngh nh vy vi cc khi nim tru tng c s dng trong cc chng trnh my tnh. Mt mu tin (record) nhn s c th c c ra, thay i v lu tr li; cn s phc th c th c dng trong cc tnh ton. Tuy vy khng th no li vit mt s phc vo tp tin lm mu tin nhn s v ngc li hai mu tin nhn s li khng th cng vi nhau c. Mt chng trnh hng i tng s xc nh c im v hnh vi c th ca cc kiu d liu, iu cho php chng ta bit mt cch chnh xc rng chng ta c th c c nhng g cc kiu d liu khc nhau. Chng ta cn c th to ra cc quan h gia cc kiu d liu tng t nhng khc nhau trong mt chng trnh hng i tng. Ngi ta thng t nhin phn loi ra mi th, thng t mi lin h 3

gia cc khi nim mi vi cc khi nim c, v thng c th thc hin suy din gia chng trn cc quan h . Hy quan nim th gii theo kiu cu trc cy, vi cc mc xy dng chi tit hn k tip nhau cho cc th h sau so vi cc th h trc. y l phng php hiu qu t chc th gii quanh chng ta. Cc chng trnh hng i tng cng lm vic theo mt phng thc tng t, trong chng cho php xy dng cc cc c cu d liu v thao tc mi da trn cc c cu c sn, mang theo cc tnh nng ca cc c cu nn m chng da trn , trong khi vn thm vo cc tnh nng mi. Lp trnh hng i tng cho php chng ta t chc d liu trong chng trnh theo mt cch tng t nh cc nh sinh hc t chc cc loi thc vt khc nhau. Theo cch ni lp trnh i tng, xe hi, cy ci, cc s phc, cc quyn sch u c gi l cc lp (Class). Mt lp l mt bn mu m t cc thng tin cu trc d liu, ln cc thao tc hp l ca cc phn t d liu. Khi mt phn t d liu c khai bo l phn t ca mt lp th n c gi l mt i tng (Object). Cc hm c nh ngha hp l trong mt lp c gi l cc phng thc (Method) v chng l cc hm duy nht c th x l d liu ca cc i tng ca lp . Mt thc th (Instance) l mt vt th c thc bn trong b nh, thc cht l mt i tng (ngha l mt i tng c cp pht vng nh). Mi mt i tng c ring cho mnh mt bn sao cc phn t d liu ca lp cn gi l cc bin thc th (Instance variable). Cc phng thc nh ngha trong mt lp c th c gi bi cc i tng ca lp . iu ny c gi l gi mt thng ip (Message) cho i tng. Cc thng ip ny ph thuc vo i tng, ch i tng no nhn thng ip mi phi lm vic theo thng ip . Cc i tng u c lp vi nhau v vy cc thay i trn cc bin th hin ca i tng ny khng nh hng g trn cc bin th hin ca cc i tng khc v vic gi thng ip cho mt i tng ny khng nh hng g n cc i tng khc.

1.2 MT S KHI NIM MI TRONG LP TRNH HNG I TNG


Trong phn ny, chng ta tm hiu cc khi nim nh s ng gi, tnh k tha v tnh a hnh. y l cc khi nim cn bn, l nn tng t tng ca lp trnh hng i tng. Hiu c khi nim ny, chng ta bc u tip cn vi phong cch lp trnh mi, phong cch lp trnh da vo i tng lm nn tng m trong quan im che du thng tin thng qua s ng gi l quan im trung tm ca vn . 1.2.1 S ng gi (Encapsulation) S ng gi l c ch rng buc d liu v thao tc trn d liu thnh mt th thng nht, trnh c cc tc ng bt ng t bn ngoi. Th thng nht ny gi l i tng. Trong mt i tng, d liu hay thao tc hay c hai c th l ring (private) hoc chung (public) ca i tng . Thao tc hay d liu ring l thuc v i tng ch c truy cp bi cc thnh phn ca i tng, iu ny ngha l thao tc hay d liu ring khng th truy cp bi cc phn khc ca chng trnh tn ti ngoi i tng. Khi thao tc hay d liu l chung, cc phn khc ca chng trnh c th truy cp n mc d n c nh ngha trong mt i tng. Cc thnh phn chung ca mt i tng dng cung cp mt giao din c iu khin cho cc thnh thnh ring ca i tng.C ch ng gi l phng thc tt thc hin c ch che du thng tin so vi cc ngn ng lp trnh cu trc. 1.2.2 Tnh k tha (Inheritance) Chng ta c th xy dng cc lp mi t cc lp c thng qua s k tha. Mt lp mi cn gi l lp dn xut (derived class), c th tha hng d liu v cc phng thc ca lp c s (base class) ban u. Trong lp ny, c th b sung cc thnh phn d liu v cc phng thc mi vo nhng thnh phn d liu v cc phng thc m n tha hng t lp c s. Mi lp (k c lp dn xut) 4

c th c mt s lng bt k cc lp dn xut. Qua c cu k tha ny, dng hnh cy ca cc lp c hnh thnh. Dng cy ca cc lp trng ging nh cc cy gia ph v th cc lp c s cn c gi l lp cha (parent class) v cc lp dn xut c gi l lp con (child class). V d 1.2: Chng ta s xy dng mt tp cc lp m t cho th vin cc n phm. C hai kiu n phm: tp ch v sch. Chng ta c th to mt n phm tng qut bng cch nh ngha cc thnh phn d liu tng ng vi s trang, m s tra cu, ngy thng xut bn, bn quyn v nh xut bn. Cc n phm c th c ly ra, ct i v c. l cc phng thc thc hin trn mt n phm. Tip chng ta nh ngha hai lp dn xut tn l tp ch v sch. Tp ch c tn, s k pht hnh v cha nhiu bi ca cc tc gi khc nhau . Cc thnh phn d liu tng ng vi cc yu t ny c t vo nh ngha ca lp tp ch. Tp ch cng cn c mt phng thc na l t mua. Cc thnh phn d liu xc nh cho sch s bao gm tn ca (cc) tc gi, loi ba (cng hay mm) v s hiu ISBN ca n. Nh vy chng ta c th thy, sch v tp ch c chung cc c trng n phm, trong khi vn c cc thuc tnh ring ca chng.

Hnh 1.1: Lp n phm v cc lp dn xut ca n. Vi tnh k tha, chng ta khng phi mt cng xy dng li t u cc lp mi, ch cn b sung c c trong cc lp dn xut cc c trng cn thit. 1.2.3 Tnh a hnh (Polymorphism) l kh nng cho mt thng ip c th thay i cch thc hin ca n theo lp c th ca i tng nhn thng ip. Khi mt lp dn xut c to ra, n c th thay i cch thc hin cc 5

phng thc no m n tha hng t lp c s ca n. Mt thng ip khi c gi n mt i tng ca lp c s, s dng phng thc nh ngha cho n trong lp c s. Nu mt lp dn xut nh ngha li mt phng thc tha hng t lp c s ca n th mt thng ip c cng tn vi phng thc ny, khi c gi ti mt i tng ca lp dn xut s gi phng thc nh ngha cho lp dn xut. V d 1.3: Xt li v d 1.2, chng ta thy rng c tp ch v v sch u phi c kh nng ly ra. Tuy nhin phng php ly ra cho tp ch c khc so vi phng php ly ra cho sch, mc d kt qu cui cng ging nhau. Khi phi ly ra tp ch, th phi s dng phng php ly ra ring cho tp ch (da trn mt bn tra cu) nhng khi ly ra sch th li phi s dng phng php ly ra ring cho sch (da trn h thng phiu lu tr). Tnh a hnh cho php chng ta xc nh mt phng thc ly ra mt tp ch hay mt cun sch. Khi ly ra mt tp ch n s dng phng thc ly ra dnh ring cho tp ch, cn khi ly ra mt cun sch th n s dng phng thc ly ra tng ng vi sch. Kt qu l ch cn mt tn phng thc duy nht c dng cho c hai cng vic tin hnh trn hai lp dn xut c lin quan, mc d vic thc hin ca phng thc thay i ty theo tng lp. Tnh a hnh da trn s ni kt (Binding), l qu trnh gn mt phng thc vi mt hm thc s. Khi cc phng thc kiu a hnh c s dng th trnh bin dch cha th xc nh hm no tng ng vi phng thc no s c gi. Hm c th c gi s tu thuc vo vic phn t nhn thng ip lc l thuc lp no, do hm c gi ch xc nh c vo lc chng trnh chy. iu ny gi l s kt ni mun (Late binding) hay kt ni lc chy (Runtime binding) v n xy ra khi chng trnh ang thc hin.

Hnh 1.2: Minh ha tnh a hnh i vi lp n phm v cc lp dn xut ca n. 6

1.3 CC NGN NG V VI NG DNG CA OOP


Xut pht t t tng ca ngn ng SIMULA67, trung tm nghin cu Palo Alto (PARC) ca hng XEROR tp trung 10 nm nghin cu hon thin ngn ng OOP u tin vi tn gi l Smalltalk. Sau cc ngn ng OOP ln lt ra i nh Eiffel, Clos, Loops, Flavors, Object Pascal, Object C, C++, Delphi, Java Chnh XEROR trn c s ngn ng OOP ra t tng giao din biu tng trn mn hnh (icon base screen interface), k t Apple Macintosh cng nh Microsoft Windows pht trin giao din ha nh ngy nay. Trong Microsoft Windows, t tng OOP c th hin mt cch r nt nht l "chng ta click vo i tng", mi i tng c th l control menu, control menu box, menu bar, scroll bar, button, minimize box, maximize box, s p ng cng vic ty theo c tnh ca i tng. Turbo Vision ca hng Borland l mt ng dng OOP tuyt vi, gip lp trnh vin khng quan tm n chi tit ca chng trnh gia din m ch cn thc hin cc ni dung chnh ca vn .

2.1 LCH S CA C++


Vo nhng nm u thp nin 1980, ngi dng bit C++ vi tn gi "C with Classes" c m t trong hai bi bo ca Bjarne Stroustrup (thuc AT&T Bell Laboratories) vi nhan "Classes: An Abstract Data Type Facility for the C Language" v "Adding Classes to C : AnExercise in Language Evolution". Trong cng trnh ny, tc gi xut khi nim lp, b sung vic kim tra kiu tham s ca hm, cc chuyn i kiu v mt s m rng khc vo ngn ng C. Bjarne Stroustrup nghin cu m rng ngn ng C nhm t n mt ngn ng m phng (simulation language) vi nhng tnh nng hng i tng. Trong nm 1983, 1984, ngn ng "C with Classes" c thit k li, m rng hn ri mt trnh bin dch ra i. V chnh t , xut hin tn gi "C++". Bjarne Stroustrup m t ngn ng C++ ln u tin trong bi bo c nhan "Data Abstraction in C". Sau mt vi hiu chnh C++ c cng b rng ri trong quyn "The C++ Programming Language" ca Bjarne Stroustrup xut hin nh du s hin din thc s ca C++, ngi lp tnh chuyn nghip t y c mt ngn ng mnh cho cc d n thc tin ca mnh. V thc cht C++ ging nh C nhng b sung thm mt s m rng quan trng, c bit l tng v i tng, lp trnh nh hng i tng.Tht ra cc tng v cu trc trong C++ xut pht vo cc nm 1970 t Simula 70 v Algol 68. Cc ngn ng ny a ra cc khi nim v lp v n th. Ada l mt ngn ng pht trin t , nhng C++ khng nh vai tr thc s ca mnh.

2.2 CC M RNG CA C++


2.2.1 Cc t kha mi ca C++ b sung cc tnh nng mi vo C, mt s t kha (keyword) mi c a vo C++ ngoi cc t kha c trong C. Cc chng trnh bng C no s dng cc tn trng vi cc t kha cn phi thay i trc khi chng trnh c dch li bng C++. Cc t kha mi ny l : asm new this 2.2.2 Cch ghi ch thch 7 catch operator throw class private try delete protected virtual friend public inline template

C++ chp nhn hai kiu ch thch. Cc lp trnh vin bng C quen vi cch ch thch bng /**/. Trnh bin dch s b qua mi th nm gia /**/. V d 2.1: Trong chng trnh sau :
CT2_1.CPP

1: /* 2: Chng trnh in cc s t 0 n 9. 3: */ 4: #include <iostream.h> 5: int main() 6: { 7: 8: 9: 10: 11: } int I; for(I = 0; I < 10 ; ++ I)// 0 - 9 cout<<I<<"\n"; // In ra 0 - 9 return 0;

Mi th nm gia /**/ t dng 1 n dng 3 u c chng trnh b qua. Chng trnh ny cn minh ha cch ch thch th hai. l cch ch thch bt u bng // dng 8 v dng 9. Chng ta chy v d 2.1, kt qu hnh 2.1.

Hnh 2.1: Kt qu ca v d 2.1 Ni chung, kiu ch thch /**/ c dng cho cc khi ch thch ln gm nhiu dng, cn kiu // c dng cho cc ch thch mt dng. 2.2.3 Dng nhp/xut chun 8

Trong chng trnh C, chng ta thng s dng cc hm nhp/xut d liu l printf() v scanf(). Trong C++ chng ta c th dng dng nhp/xut chun (standard input/output stream) nhp/xut d liu thng qua hai bin i tng ca dng (stream object) l cout v cin. V d 2.2: Chng trnh nhp vo hai s. Tnh tng v hiu ca hai s va nhp.
CT2_2.CPP

1: #include <iostream.h> 2: int main() 3: { 4: 5: 6: 7: 8: 9: 10: 11: 12: } int X, Y; cout<< "Nhap vao mot so X:"; cin>>X; cout<< "Nhap vao mot so Y:"; cin>>Y; cout<<"Tong cua chung:"<<X+Y<<"\n"; cout<<"Hieu cua chung:"<<X-Y<<"\n"; return 0;

thc hin dng xut chng ta s dng bin cout (console output) kt hp vi ton t chn (insertion operator) << nh cc dng 5, 7, 9 v 10. Cn dng nhp chng ta s dng bin cin (console input) kt hp vi ton t trch (extraction operator) >> nh cc dng 6 v 8. Khi s dng cout hay cin, chng ta phi ko file iostream.h nh dng 1. Chng ta s tm hiu k v dng nhp/xut chng 8. Chng ta chy v d 2.2 , kt qu hnh 2.2.

Hnh 2.2: Kt qu ca v d 2.2

Hnh 2.3: Dng nhp/xut d liu 2.2.4 Cch chuyn i kiu d liu Hnh thc chuyn i kiu trong C tng i ti ngha, v vy C++ trang b thm mt cch chuyn i kiu ging nh mt lnh gi hm. V d 2.3:
CT2_3.CPP

1: #include <iostream.h> 2: int main() 3: { 4: 5: 6: 7: 8: 9: 10: 11: } int X = 200; long Y = (long) X; //Chuyn i kiu theo cch ca C long Z = long(X); // Chuyn i kiu theo cch mi ca C++ cout<< "X = "<<X<<"\n"; cout<< "Y = "<<Y<<"\n"; cout<< "Z = "<<Z<<"\n"; return 0;

Chng ta chy v d 2.3 , kt qu hnh 2.4. 10

Hnh 2.4: Kt qu ca v d 2.3 2.2.5 V tr khai bo bin Trong chng trnh C i hi tt c cc khai bo bn trong mt phm vi cho trc phi c t ngay u ca phm vi . iu ny c ngha l tt c cc khai bo ton cc phi t trc tt c cc hm v cc khai bo cc b phi c tin hnh trc tt c cc lnh thc hin. Ngc li C++ cho php chng ta khai bo linh hot bt k v tr no trong mt phm vi cho trc (khng nht thit phi ngay u ca phm vi), chng ta xen k vic khai bo d liu vi cc cu lnh thc hin. V d 2.4: Chng trnh m phng mt my tnh n gin
CT2_4.CPP

1: #include <iostream.h> 2: int main() 3: { 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: int X; cout<< "Nhap vao so thu nhat:"; cin>>X; int Y; cout<< "Nhap vao so thu hai:"; cin>>Y; char Op; cout<<"Nhap vao toan tu (+-*/):"; cin>>Op; switch(Op) { case +: cout<<"Ket qua:"<<X+Y<<"\n"; break; case -:

11

19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: } }

cout<<"Ket qua:"<<X-Y<<"\n"; break; case *: cout<<"Ket qua:"<<long(X)*Y<<"\n"; break; case /: if (Y) cout<<"Ket qua:"<<float(X)/Y<<"\n"; else cout<<"Khong the chia duoc!" <<"\n"; 9; 9; break; default : cout<<"Khong hieu toan tu nay!"<<"\n";

return 0;

Trong chng trnh chng ta xen k khai bo bin vi lnh thc hin dng 4 n dng 12. Chng ta chy v d 2.4, kt qu hnh 2.5.

Hnh 2.5: Kt qu ca v d 2.4 Khi khai bo mt bin trong chng trnh, bin s c hiu lc trong phm vi ca chng trnh k t v tr n xut hin. V vy chng ta khng th s dng mt bin c khai bo bn di n. 2.2.6 Cc bin const

12

Trong ANSI C, mun nh ngha mt hng c kiu nht nh th chng ta dng bin const (v nu dng #define th to ra cc hng khng c cha thng tin v kiu). Trong C++, cc bin const linh hot hn mt cch ng k: C++ xem const cng nh #define nu nh chng ta mun dng hng c tn trong chng trnh. Chnh v vy chng ta c th dng const quy nh kch thc ca mt mng nh on m sau: const int ArraySize = 100; int X[ArraySize]; Khi khai bo mt bin const trong C++ th chng ta phi khi to mt gi tr ban u nhng i vi ANSI C th khng nht thit phi lm nh vy (v trnh bin dch ANSI C t ng gn tr zero cho bin const nu chng ta khng khi to gi tr ban u cho n). Phm vi ca cc bin const gia ANSI C v C++ khc nhau. Trong ANSI C, cc bin const c khai bo bn ngoi mi hm th chng c phm vi ton cc, iu ny ngha l chng c th nhn thy c bn ngoi file m chng c nh ngha, tr khi chng c khai bo l static. Nhng trong C++, cc bin const c hiu mc nh l static. 2.2.7 V struct, union v enum Trong C++, cc struct v union thc s cc cc kiu class. Tuy nhin c s thay i i vi C++. l tn ca struct v union c xem lun l tn kiu ging nh khai bo bng lnh typedef vy. Trong C, chng ta c th c on m sau : struct Complex { float Real; float Imaginary; }; .. struct Complex C; Trong C++, vn tr nn n gin hn: struct Complex { float Real; float Imaginary; }; .. Complex C; 13

Quy nh ny cng p dng cho c union v enum. Tuy nhin tng thch vi C, C++ vn chp nhn c php c. Mt kiu union c bit c thm vo C++ gi l union nc danh (anonymous union). N ch khai bo mt lot cc trng(field) dng chung mt vng a ch b nh. Mt union nc danh khng c tn tag, cc trng c th c truy xut trc tip bng tn ca chng. Chng hn nh on m sau: union { int Num; float Value; }; C hai Num v Value u dng chung mt v tr v khng gian b nh. Tuy nhin khng ging nh kiu union c tn, cc trng ca union nc danh th c truy xut trc tip, chng hn nh sau: Num = 12; Value = 30.56; 2.2.8 Ton t nh phm vi Ton t nh phm vi (scope resolution operator) k hiu l ::, n c dng truy xut mt phn t b che bi phm vi hin thi. V d 2.5 :
CT2_5.CPP

1: #include <iostream.h> 2: int X = 5; 3: int main() 4: { 5: 6: 7: 8: 9: } int X = 16; cout<< "Bien X ben trong = "<<X<<"\n"; cout<< "Bien X ben ngoai = "<<::X<<"\n"; return 0;

Chng ta chy v d 2.5, kt qu hnh 2.6 14

Hnh 2.6: Kt qu ca v d 2.5 Ton t nh phm vi cn c dng trong cc nh ngha hm ca cc phng thc trong cc lp, khai bo lp ch ca cc phng thc ang c nh ngha . Ton t nh phm vi cn c th c dng phn bit cc thnh phn trng tn ca cc lp c s khc nhau. 2.2.9 Ton t new v delete Trong cc chng trnh C, tt c cc cp pht ng b nh u c x l thng qua cc hm th vin nh malloc(), calloc() v free(). C++ nh ngha mt phng thc mi thc hin vic cp pht ng b nh bng cch dng hai ton t new v delete. S dng hai ton t ny s linh hot hn rt nhiu so vi cc hm th vin ca C. on chng trnh sau dng cp pht vng nh ng theo li c in ca C. int *P; P = malloc(sizeof(int)); if (P==NULL) printf("Khong con du bo nho de cap phat\n"); else { *P = 290; printf("%d\n", *P); free(P); } Trong C++, chng ta c th vit li on chng trnh trn nh sau: int *P; P = new int; if (P==NULL) cout<<"Khong con du bo nho de cap phat\n"; else 15

{ *P = 290; cout<<*P<<"\n"; delete P; } Chng ta nhn thy rng, cch vit ca C++ sng sa v d s dng hn nhiu. Ton t new thay th cho hm malloc() hay calloc() ca C c c php nh sau : new type_name new ( type_name ) new type_name initializer new ( type_name ) initializer Trong : type_name: M t kiu d liu c cp pht. Nu kiu d liu m t phc tp, n c th c t bn trong cc du ngoc. initializer: Gi tr khi ng ca vng nh c cp pht. Nu ton t new cp pht khng thnh cng th n s tr v gi tr NULL. Cn ton t delete thay th hm free() ca C, n c c php nh sau : delete pointer delete [] pointer Chng ta c th va cp pht va khi ng nh sau : int *P; P = new int(100); if (P!=NULL) { cout<<*P<<"\n"; delete P; 16

} else cout<<"Khong con du bo nho de cap phat\n"; cp pht mt mng, chng ta lm nh sau : int *P; P = new int[10]; //Cp pht mng 10 s nguyn if (P!=NULL) { for(int I = 0;I<10;++) P[I]= I; for(I = 0;I<10;++) cout<<P[I]<<"\n"; delete []P; } else cout<<"Khong con du bo nho de cap phat\n"; Ch : i vi vic cp pht mng chng ta khng th va cp pht va khi ng gi tr cho chng, chng hn on chng trnh sau l sai : int *P; P = new (int[10])(3); //Sai !!! V d 2.6: Chng trnh to mt mng ng, khi ng mng ny vi cc gi tr ngu nhin v sp xp chng.
CT2_6.CPP

1: #include <iostream.h> 2: #include <time.h> 3: #include <stdlib.h> 4: int main()

17

5: { 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: } cout<<"\nMang sau khi sap xep\n"; for(I=0;I<N;++I) cout<<P[I]<<" "; } srand((unsigned)time(NULL)); for(int I=0;I<N;++I) P[I]=rand()%100; //To cc s ngu nhin t 0 n 99 cout<<"Mang truoc khi sap xep\n"; for(I=0;I<N;++I) cout<<P[I]<<" "; for(I=0;I<N-1;++I) for(int J=I+1;J<N;++J) if (P[I]>P[J]) { int Temp=P[I]; P[I]=P[J]; P[J]=Temp; int N; cout<<"Nhap vao so phan tu cua mang:"; cin>>N; int *P=new int[N]; if (P==NULL) { cout<<"Khong con bo nho de cap phat\n"; return 1;

18

32: 33: 34: }

delete []P; return 0;

Chng ta chy v d 2.6, kt qu hnh 2.7

Hnh 2.7: Kt qu ca v d 2.6 V d 2.7: Chng trnh cng hai ma trn trong mi ma trn c cp pht ng.Chng ta c th xem mng hai chiu nh mng mt chiu nh hnh 2.8

Hnh 2.8: Mng hai chiu c th xem nh mng mt chiu. Gi X l mng hai chiu c kch thc m dng v n ct.A l mng mt chiu tng ng.Nu X[i][j] chnh l A[k] th k = i*n + j Chng ta c chng trnh nh sau :
CT2_7.CPP

1: #include <iostream.h>

19

2: #include <conio.h> 3: //prototype 4: void AddMatrix(int * A,int *B,int*C,int M,int N); 5: int AllocMatrix(int **A,int M,int N); 6: void FreeMatrix(int *A); 7: void InputMatrix(int *A,int M,int N,char Symbol); 8: void DisplayMatrix(int *A,int M,int N); 9: 10: int main() 11: { 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: } //Cp pht vng nh cho ma trn B if (!AllocMatrix(&B,M,N)) { clrscr(); cout<<"Nhap so dong cua ma tran:"; cin>>M; cout<<"Nhap so cot cua ma tran:"; cin>>N; //Cp pht vng nh cho ma trn A if (!AllocMatrix(&A,M,N)) { //endl: Xut ra k t xung dng (\n) cout<<"Khong con du bo nho!"<<endl; return 1; int M,N; int *A = NULL,*B = NULL,*C = NULL;

20

29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: } }

cout<<"Khong con du bo nho!"<<endl; FreeMatrix(A);//Gii phng vng nh A return 1;

//Cp pht vng nh cho ma trn C if (!AllocMatrix(&C,M,N)) { cout<<"Khong con du bo nho!"<<endl; FreeMatrix(A);//Gii phng vng nh A FreeMatrix(B);//Gii phng vng nh B return 1;

cout<<"Nhap ma tran thu 1"<<endl; InputMatrix(A,M,N,'A'); cout<<"Nhap ma tran thu 2"<<endl; InputMatrix(B,M,N,'B'); clrscr(); cout<<"Ma tran thu 1"<<endl; DisplayMatrix(A,M,N); cout<<"Ma tran thu 2"<<endl; DisplayMatrix(B,M,N); AddMatrix(A,B,C,M,N); cout<<"Tong hai ma tran"<<endl; DisplayMatrix(C,M,N); FreeMatrix(A);//Gii phng vng nh A FreeMatrix(B);//Gii phng vng nh B FreeMatrix(C);//Gii phng vng nh C

21

56: 57: }

return 0;

68: //Cng hai ma trn 69: void AddMatrix(int *A,int *B,int*C,int M,int N) 70: { 71: 72: 73: } 74: //Cp pht vng nh cho ma trn 75: int AllocMatrix(int **A,int M,int N) 76: { 77: 78: 79: 80: 81: } 82: //Gii phng vng nh 83: void FreeMatrix(int *A) 84: { 85: 86: 87: } 88: //Nhp cc gi tr ca ma trn 89: void InputMatrix(int *A,int M,int N,char Symbol) 90: { 91: 92: for(int I=0;I<M;++I) for(int J=0;J<N;++J) if (A!=NULL) delete [] A; *A = new int [M*N]; if (*A == NULL) return 0; return 1; for(int I=0;I<M*N;++I) C[I] = A[I] + B[I];

22

93 94: 95: 96: 97: }

{ cout<<Symbol<<"["<<I<<"]["<<J<<"]="; cin>>A[I*N+J]; }

100: //Hin th ma trn 101: void DisplayMatrix(int *A,int M,int N) 102: { 103: 104: 105: 106: 107: ky tu 108: 109: 110: 111: 112: } } cout<<endl; } { out.width(7);//Hien thi canh le phai voi chieu dai 7 for(int I=0;I<M;++I) { for(int J=0;J<N;++J)

cout<<A[I*N+J];

Chng ta chy v du 2.7 , kt qu hnh 2.9

23

Hnh 2.9: Kt qu ca v d 2.7 Mt cch khc cp pht mng hai chiu A gm M dng v N ct nh sau: int ** A = new int *[M]; int * Tmp = new int[M*N]; for(int I=0;I<M;++I) { A[I]=Tmp; Tmp+=N; } //Thao tc trn mng hai chiu A .. delete [] *A; delete [] A; Ton t new cn c mt thun li khc, l tt c cc li cp pht ng u c th bt c bng mt hm x l li do ngi dng t nh ngha. C++ c nh ngha mt con tr (pointer) tr n hm c bit. Khi ton t new c s dng cp pht ng v mt li xy ra do cp pht, C++ t gi n hm c ch bi con tr ny. nh ngha ca con tr ny nh sau: 24

typedef void (*pvf)(); pvf _new_handler(pvf p); iu ny c ngha l con tr _new_handler l con tr tr n hm khng c tham s v khng tr v gi tr. Sau khi chng ta nh ngha hm nh vy v gn a ch ca n cho _new_handler chng ta c th bt c tt c cc li do cp pht ng. V d 2.8:
CT2_8.CPP

1: #include <iostream.h> 2: #include <stdlib.h> 3: #include <new.h> 4: 5: void MyHandler(); 6: 7: unsigned long I = 0; 9; 8: void main() 9: { 10: 11: 12: 13: 14: 15: } 16: 17: void MyHandler() 18: { 19: 20: 21: 22: } cout<<"Lan cap phat thu "<<I<<endl; cout<<"Khong con du bo nho!"<<endl; exit(1); int *A; _new_handler = MyHandler; for( ; ; ++I) A = new int;

25

S dng con tr _new_handler chng ta phi include file new.h nh dng 3. Chng ta chy v d 2.8, kt qu hnh 2.10.

Hnh 2.10: Kt qu ca v d 2.8 Th vin cng cn c mt hm c nh ngha trong new.h l hm c prototype sau : void ( * set_new_handler(void (* my_handler)() ))(); Hm set_new_handler() dng gn mt hm cho _new_handler. V d 2.9:
CT2_9.CPP

1: #include <iostream.h> 2: #include <new.h> 3: #include <stdlib.h> 4: 5: void MyHandler(); 6: 7: int main(void) 8: { 9: 10: 11: 12: 13: 14: 15: 16: } 17: set_new_handler(MyHandler); Ptr = new char[64000u]; set_new_handler(0); //Thit lp li gi tr mc nh return 0; char *Ptr;

26

18: void MyHandler() 19: { 20: 21: 22 } cout <<endl<<"Khong con du bo nho"; exit(1);

Chng ta chy v d 2.9, kt qu hnh 2.11

Hnh 2.11: Kt qu ca v d 2.9 2.2.10 Hm inline Mt chng trnh c cu trc tt s dng cc hm chia chng trnh thnh cc n v c lp c logic ring. Tuy nhin, cc hm thng phi cha mt lot cc x l im vo (entry point): tham s phi c y vo stack, mt lnh gi phi c thc hin v sau vic quay tr v cng phi c thc hin bng cch gii phng cc tham s ra khi stack. Khi cc x l im vo chm chp thng cc lp trnh vin C phi s dng cch chp lp li cc on chng trnh nu mun tng hiu qu. trnh khi phi x l im vo, C++ trang b thm t kha inline loi vic gi hm. Khi trnh bin dch s khng bin dch hm ny nh mt on chng trnh ring bit m n s c chn thng vo cc ch m hm ny c gi. iu ny lm gim vic x l im vo m vn cho php mt chng trnh c t chc di dng c cu trc. C php ca hm inline nh sau : inline data_type function_name ( parameters ) { .. } Trong : data_type: Kiu tr v ca hm. Function_name:Tn ca hm. Parameters: Cc tham s ca hm. V d 2.10: Tnh th tch ca hnh lp phng
CT2_10.CPP

27

1: #include <iostream.h> 2: inline float Cube(float S) 3: { 4: return S*S*S; 5: } 6: 7: int main() 8: { 9: 10: 11: 12: 13: 14: } cout<<"Nhap vao chieu dai canh cua hinh lap phuong:"; float Side; cin>>Side; cout<<"The tich cua hinh lap phuong = "<<Cube(Side); return 0;

Chng ta chy v d 2.10, kt qu hnh 2.12

Hnh 2.12: Kt qu ca v d 2.10 Ch : S dng hm inline s lm cho chng trnh ln ln v trnh bin dch chn on chng trnh vo cc ch m hm ny c gi. Do thng cc hm inline thng l cc hm nh, t phc tp. Cc hm inline phi c nh ngha trc khi s dng. v d 2.10 chng ta sa li nh sau th chng trnh s b bo li:
A.CPP

1: #include <iostream.h> 2: float Cube(float S); 3: int main()

28

4: { 5: 6: 7: 8: 9: 10: } 11: 12: inline float Cube(float S) 13: { 14: 15: } return S*S*S; cout<<"Nhap vao chieu dai canh cua hinh lap phuong:"; float Side; cin>>Side; cout<<"The tich cua hinh lap phuong = "<<Cube(Side); return 0;

Cc hm quy khng c l hm inline. 2.2.11 Cc gi tr tham s mc nh Mt trong cc c tnh ni bt nht ca C++ l kh nng nh ngha cc gi tr tham s mc nh cho cc hm. Bnh thng khi gi mt hm, chng ta cn gi mt gi tr cho mi tham s c nh ngha trong hm , chng hn chng ta c on chng trnh sau: void MyDelay(long Loops); //prototype .. void MyDelay(long Loops) { for(int I = 0; I < Loops; ++I) ; } Mi khi hm MyDelay() c gi chng ta phi gi cho n mt gi tr cho tham s Loops. Tuy nhin, trong nhiu trng hp chng ta c th nhn thy rng chng ta lun lun gi hm MyDelay() vi cng mt gi tr Loops no . Mun vy chng ta s dng gi tr mc nh cho tham s Loops, gi s 29

chng ta mun gi tr mc nh cho tham s Loops l 1000. Khi on m trn c vit li nh sau : void MyDelay(long Loops = 1000); //prototype .. void MyDelay(long Loops) { for(int I = 0; I < Loops; ++I) ; } Mi khi gi hm MyDelay() m khng gi mt tham s tng ng th trnh bin dch s t ng gn cho tham s Loops gi tr 1000. MyDelay(); // Loops c gi tr l 1000 MyDelay(5000); // Loops c gi tr l 5000 Gi tr mc nh cho tham s c th l mt hng, mt hm, mt bin hay mt biu thc. V d 2.11: Tnh th tch ca hnh hp
CT2_11.CPP

1: #include <iostream.h> 2: int BoxVolume(int Length = 1, int Width = 1, int Height = 1); 3: 4: int main() 5: { 6: 7: 8: 9: 10: 11: 12: cout << "The tich hinh hop mac dinh: " << BoxVolume() << endl << endl << "The tich hinh hop voi chieu dai=10,do rong=1,chieu cao=1:" << BoxVolume(10) << endl << endl << "The tich hinh hop voi chieu dai=10,do rong=5,chieu cao=1:" << BoxVolume(10, 5) << endl << endl << "The tich hinh hop voi chieu dai=10,do rong=5,chieu cao=2:"

30

13: 14: 15: }

<< BoxVolume(10, 5, 2)<< endl; return 0;

16: //Tnh th tch ca hnh hp 17: int BoxVolume(int Length, int Width, int Height) 18: { 19: 20: } return Length * Width * Height;

Chng ta chy v d 2.11, kt qu hnh 2.13

Hnh 2.13: Kt qu ca v d 2.11 Ch : Cc tham s c gi tr mc nh ch c cho trong prototype ca hm v khng c lp li trong nh ngha hm (V trnh bin dch s dng cc thng tin trong prototype ch khng phi trong nh ngha hm to mt lnh gi). Mt hm c th c nhiu tham s c gi tr mc nh. Cc tham s c gi tr mc nh cn phi c nhm li vo cc tham s cui cng (hoc duy nht) ca mt hm. Khi gi hm c nhiu tham s c gi tr mc nh, chng ta ch c th b bt cc tham s theo th t t phi sang tri v phi b lin tip nhau, chng hn chng ta c on chng trnh nh sau: int MyFunc(int a= 1, int b , int c = 3, int d = 4); //prototype sai!!! int MyFunc(int a, int b = 2 , int c = 3, int d = 4); //prototype ng .. 31

MyFunc(); // Li do tham s a khng c gi tr mc nh MyFunc(1);// OK, cc tham s b, c v d ly gi tr mc nh MyFunc(5, 7); // OK, cc tham s c v d ly gi tr mc nh MyFunc(5, 7, , 8); // Li do cc tham s b b phi lin tip nhau 2.2.12 Php tham chiu Trong C, hm nhn tham s l con tr i hi chng ta phi thn trng khi gi hm. Chng ta cn vit hm hon i gi tr gia hai s nh sau: void Swap(int *X, int *Y); { int Temp = *X; *X = *Y; *Y = *Temp; } hon i gi tr hai bin A v B th chng ta gi hm nh sau: Swap(&A, &B); R rng cch vit ny khng c thun tin lm. Trong trng hp ny, C++ a ra mt kiu bin rt c bit gi l bin tham chiu (reference variable). Mt bin tham chiu ging nh l mt b danh ca bin khc. Bin tham chiu s lm cho cc hm c thay i ni dung cc tham s ca n c vit mt cch thanh thot hn. Khi hm Swap() c vit nh sau: void Swap(int &X, int &Y); { int Temp = X; X = Y; Y = Temp ; } Chng ta gi hm nh sau : Swap(A, B); 32

Vi cch gi hm ny, C++ t gi a ch ca A v B lm tham s cho hm Swap(). Cch dng bin tham chiu cho tham s ca C++ tng t nh cc tham s c khai bo l Var trong ngn ng Pascal. Tham s ny c gi l tham s kiu tham chiu (reference parameter). Nh vy bin tham chiu c c php nh sau : data_type & variable_name; Trong : data_type: Kiu d liu ca bin. variable_name: Tn ca bin Khi dng bin tham chiu cho tham s ch c a ch ca n c gi i ch khng phi l ton b cu trc hay i tng nh hnh 2.14, iu ny rt hu dng khi chng ta gi cu trc v i tng ln cho mt hm.

Hnh 2.14: Mt tham s kiu tham chiu nhn mt tham chiu ti mt bin c chuyn cho tham s ca hm. V d 2.12: Chng trnh hon i gi tr ca hai bin.
CT2_12.CPP

1: #include <iostream.h> 2: //prototype 3 void Swap(int &X,int &Y); 4: 5: int main() 6: { 7: int X = 10, Y = 5;

33

8: 9: 10: 11: 12: } 13:

cout<<"Truoc khi hoan doi: X = "<<X<<",Y = "<<Y<<endl; Swap(X,Y); cout<<"Sau khi hoan doi: X = "<<X<<",Y = "<<Y<<endl; return 0;

14: void Swap(int &X,int &Y) 15: { 16: 17: 18: 19: } int Temp=X; X=Y; Y=Temp;

Chng ta chy v d 2.12, kt qu hnh 2.15

Hnh 2.15: Kt qu ca v d 2.12 i khi chng ta mun gi mt tham s no bng bin tham chiu cho hiu qu, mc d chng ta khng mun gi tr ca n b thay i th chng ta dng thm t kha const nh sau : int MyFunc(const int & X); Hm MyFunc() s chp nhn mt tham s X gi bng tham chiu nhng const xc nh rng X khng th b thay i.Bin tham chiu c th s dng nh mt b danh ca bin khc (b danh n gin nh mt tn khc ca bin gc), chng hn nh on m sau : int Count = 1; int & Ref = Count; //To bin Ref nh l mt b danh ca bin Count ++Ref; //Tng bin Count ln 1 (s dng b danh ca bin Count) Cc bin tham chiu phi c khi ng trong phn khai bo ca chng v chng ta khng th gn li mt b danh ca bin khc cho chng. Chng hn on m sau l sai: int X = 1; int & Y; //Li: Y phi c khi ng.

34

Khi mt tham chiu c khai bo nh mt b danh ca bin khc, mi thao tc thc hin trn b danh chnh l thc hin trn bin gc ca n. Chng ta c th ly a ch ca bin tham chiu v c th so snh cc bin tham chiu vi nhau (phi tng thch v kiu tham chiu). V d 2.13: Mi thao tc trn trn b danh chnh l thao tc trn bin gc ca n.
CT2_13.CPP

1: #include <iostream.h> 2: int main() 3: { 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: } cout<<"X="<<X<<endl<<"Y="<<Y<<endl; Y *= 3; cout<<"X="<<X<<endl<<"Y="<<Y<<endl; Y = Z; cout<<"X="<<X<<endl<<"Y="<<Y<<endl; return 0; int X = 3; int &Y = X; //Y la b danh ca X int Z = 100;

Chng ta chy v d 2.13, kt qu hnh 2.16

Hnh 2.16: Kt qu ca v d 2.13 V d 2.14: Ly a ch ca bin tham chiu

35

CT2_14.CPP

1: #include <iostream.h> 2: int main() 3: { 4: 5: 6: 7: 8: 9: 10: } cout<<"Dia chi cua X = "<<&X<<endl; cout<<"Dia chi cua bi danh Y= "<<&Y<<endl; return 0; int X = 3; int &Y = X; //Y la b danh ca X

Chng ta chy v d 2.14, kt qu hnh 2.17

Hnh 2.17: Kt qu ca v d 2.14 Chng ta c th to ra bin tham chiu vi vic khi ng l mt hng, chng hn nh on m sau :int & Ref = 45; Trong trng hp ny, trnh bin dch to ra mt bin tm thi cha tr hng v bin tham chiu chnh l b danh ca bin tm thi ny. iu ny gi l tham chiu c lp (independent reference). Cc hm c th tr v mt tham chiu, nhng iu ny rt nguy him. Khi hm tr v mt tham chiu ti mt bin cc b ca hm th bin ny phi c khai bo l static, ngc li tham chiu ti n th khi hm kt thc bin cc b ny s b b qua. Chng hn nh on chng trnh sau: int & MyFunc() { static int X = 200; //Nu khng khai bo l static th iu ny rt nguy him. return X; } Khi mt hm tr v mt tham chiu, chng ta c th gi hm phi bn tri ca mt php gn. 36

V d 2.15:
CT2_15.CPP

1: #include <iostream.h> 2: 3: int X = 4; 4: //prototype 5: int & MyFunc(); 6: 7: int main() 8: { 9: 10: 11: 12: 13: 14: } 15: 16: int & MyFunc() 17: { 18: 19: } return X; cout<<"X="<<X<<endl; cout<<"X="<<MyFunc()<<endl; MyFunc() = 20; //Ngha l X = 20 cout<<"X="<<X<<endl; return 0;

Chng ta chy v d 2.15, kt qu hnh 2.18

Hnh 2.18: Kt qu ca v d 2.15 37

Ch : Mc d bin tham chiu trng ging nh l bin con tr nhng chng khng th l bin con tr do chng khng th c dng cp pht ng. Chng ta khng th khai bo mt bin tham chiu ch n bin tham chiu hoc bin con tr ch n bin tham chiu. Tuy nhin chng ta c th khai bo mt bin tham chiu v bin con tr nh on m sau: int X; int *P = &X; int * & Ref = P; 2.2.13 Php a nng ha (Overloading) : Vi ngn ng C++, chng ta c th a nng ha cc hm v cc ton t (operator). a nng ha l phng php cung cp nhiu hn mt nh ngha cho tn hm cho trong cng mt phm vi. Trnh bin dch s la chn phin bn thch hp ca hm hay ton t da trn cc tham s m n c gi. 2.2.13.1 a nng ha cc hm (Functions overloading) : Trong ngn ng C cng nh mi ngn ng my tnh khc, mi hm u phi c mt tn phn bit. i khi y l mt iu phiu toi. Chng hn nh trong ngn ng C, c rt nhiu hm tr v tr tuyt i ca mt tham s l s, v cn thit phi c tn phn bit nn C phi c hm ring cho mi kiu d liu s, do vy chng ta c ti ba hm khc nhau tr v tr tuyt i ca mt tham s : int abs(int i); long labs(long l); double fabs(double d); Tt c cc hm ny u cng thc hin mt cha nng nn chng ta thy iu ny nghch l khi phi c ba tn khc nhau. C++ gii quyt iu ny bng cch cho php chng ta to ra cc hm khc nhau c cng mt tn. y chnh l a nng ha hm. Do trong C++ chng ta c th nh ngha li cc hm tr v tr tuyt i thay th cc hm trn nh sau : int abs(int i); long abs(long l); double abs(double d); V d 2.16:
CT2_16.CPP

1: #include <iostream.h> 2: #include <math.h> 3: 4: int MyAbs(int X); 5: long MyAbs(long X); 6: double MyAbs(double X); 7:

38

8: int main() 9: { 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: } 21: 22: int MyAbs(int X) 23: { 24: 25: } 26: 27: long MyAbs(long X) 28: { 29: 30: } 31: 32: double MyAbs(double X) 33: { 34: return fabs(X); return labs(X); return abs(X); int X = -7; long Y = 200000l; double Z = -35.678; cout<<"Tri tuyet doi cua so nguyen (int) "<<X<<" la " <<MyAbs(X)<<endl; cout<<"Tri tuyet doi cua so nguyen (long int) "<<Y<<" la " <<MyAbs(Y)<<endl; cout<<"Tri tuyet doi cua so thuc "<<Z<<" la " <<MyAbs(Z)<<endl; return 0;

39

35: }

Chng ta chy v d 2.16 , kt qu hnh 2.19

Hnh 2.19: Kt qu ca v d 2.16 Trnh bin dch da vo s khc nhau v s cc tham s, kiu ca cc tham s c th xc nh chnh xc phin bn ci t no ca hm MyAbs() thch hp vi mt lnh gi hm c cho, chng hn nh: MyAbs(-7); //Gi hm int MyAbs(int) MyAbs(-7l); //Gi hm long MyAbs(long) MyAbs(-7.5); //Gi hm double MyAbs(double) Qu trnh tm c hm c a nng ha cng l qu trnh c dng gii quyt cc trng hp nhp nhng ca C++. Chng hn nh nu tm thy mt phin bn nh ngha no ca mt hm c a nng ha m c kiu d liu cc tham s ca n trng vi kiu cc tham s gi ti trong lnh gi hm th phin bn hm s c gi. Nu khng trnh bin dch C++ s gi n phin bn no cho php chuyn kiu d dng nht. MyAbs(c); //Gi int MyAbs(int) MyAbs(2.34f); //Gi double MyAbs(double) Cc php chuyn kiu c sn s c u tin hn cc php chuyn kiu m chng ta to ra (chng ta s xem xt cc php chuyn kiu t to chng 3). Chng ta cng c th ly a ch ca mt hm c a nng ha sao cho bng mt cch no chng ta c th lm cho trnh bin dch C++ bit c chng ta cn ly a ch ca phin bn hm no c trong nh ngha. Chng hn nh: int (*pf1)(int); long (*pf2)(long); int (*pf3)(double); pf1 = MyAbs; //Tr n hm int MyAbs(int) pf2 = MyAbs; //Tr n hm long MyAbs(long) pf3 = MyAbs; //Li!!! (khng c phin bn hm no i snh) Cc gii hn ca vic a nng ha cc hm: 40

Bt k hai hm no trong tp cc hm a nng phi c cc tham s khc nhau. Cc hm a nng ha vi danh sch cc tham s cng kiu ch da trn kiu tr v ca hm th trnh bin dch bo li. Chng hn nh, cc khai bo sau l khng hp l: void Print(int X); int Print(int X); Khng c cch no trnh bin dch nhn bit phin bn no c gi nu gi tr tr v b b qua. Nh vy cc phin bn trong vic a nng ha phi c s khc nhau t nht v kiu hoc s tham s m chng nhn c. Cc khai bo bng lnh typedef khng nh ngha kiu mi. Chng ch thay i tn gi ca kiu c. Chng khng nh hng ti c ch a nng ha hm. Chng ta hy xem xt on m sau: typedef char * PSTR; void Print(char * Mess); void Print(PSTR Mess); Hai hm ny c cng danh sch cc tham s, do on m trn s pht sinh li. i vi kiu mng v con tr c xem nh ng nht i vi s phn bit khc nhau gia cc phin bn hm trong vic a nng ha hm. Chng hn nh on m sau se pht sinh li: void Print(char * Mess); void Print(char Mess[]); Tuy nhin, i vi mng nhiu chiu th c s phn bit gia cc phin bn hm trong vic a nng ha hm, chng hn nh on m sau hp l: void Print(char Mess[]); void Print(char Mess[][7]); void Print(char Mess[][9][42]); const v cc con tr (hay cc tham chiu) c th dng phn bit, chng hn nh on m sau hp l: void Print(char *Mess); 41

void Print(const char *Mess); 2.2.13.2 a nng ha cc ton t (Operators overloading) : Trong ngn ng C, khi chng ta t to ra mt kiu d liu mi, chng ta thc hin cc thao tc lin quan n kiu d liu thng thng qua cc hm, iu ny tr nn khng thoi mi. V d 2.17: Chng trnh ci t cc php ton cng v tr s phc

CT2_17.CPP

1: #include <stdio.h> 2: /* nh ngha s phc */ 3: typedef struct 4: { 5: 6: double Real; double Imaginary;

7: }Complex; 8: 9: Complex SetComplex(double R,double I);

10: Complex AddComplex(Complex C1,Complex C2); 11: Complex SubComplex(Complex C1,Complex C2); 12: void DisplayComplex(Complex C); 13: 14: int main(void) 15: { 16: 17: 18: 19: 20: 21: C1 = SetComplex(1.0,2.0); C2 = SetComplex(-3.0,4.0); printf("\nSo phuc thu nhat:"); DisplayComplex(C1); Complex C1,C2,C3,C4;

42

22: 23: 24: 25: 26: 27: 28: 29: 30: 31: } 32:

printf("\nSo phuc thu hai:"); DisplayComplex(C2); C3 = AddComplex(C1,C2); //Hi bt tin !!! C4 = SubComplex(C1,C2); printf("\nTong hai so phuc nay:"); DisplayComplex(C3); printf("\nHieu hai so phuc nay:"); DisplayComplex(C4); return 0;

33: /* t gi tr cho mt s phc */ 34: Complex SetComplex(double R,double I) 35: { 36: 37: 38: 39: 40: 41: } 42: /* Cng hai s phc */ 43: Complex AddComplex(Complex C1,Complex C2) 44: { 45: 46: 47: 48: Tmp.Real = C1.Real+C2.Real; Tmp.Imaginary = C1.Imaginary+C2.Imaginary; Complex Tmp; Tmp.Real = R; Tmp.Imaginary = I; return Tmp; Complex Tmp;

43

49: 50: } 51:

return Tmp;

52: /* Tr hai s phc */ 53: Complex SubComplex(Complex C1,Complex C2) 54: { 55: 56: 57: 58: 59: 60: } 61: 62: /* Hin th s phc */ 63: void DisplayComplex(Complex C) 64: { 65: 66: } printf("(%.1lf,%.1lf)",C.Real,C.Imaginary); Tmp.Real = C1.Real-C2.Real; Tmp.Imaginary = C1.Imaginary-C2.Imaginary; return Tmp; Complex Tmp;

Chng ta chy v d 2.17, kt qu hnh 2.20

Hnh 2.20: Kt qu ca v d 2.17 Trong chng trnh v d 2.17, chng ta nhn thy vi cc hm va ci t dng cng v tr hai s phc 1+2i v 3+4i; ngi lp trnh hon ton khng thoi mi khi s dng bi v thc cht thao tc cng v tr l cc ton t ch khng phi l hm. khc phc yu im 44

ny, trong C++ cho php chng ta c th nh ngha li chc nng ca cc ton t c sn mt cch tin li v t nhin hn rt nhiu. iu ny gi l a nng ha ton t. Khi chng trnh v d 2.17 c vit nh sau: V d 2.18:
CT2_18.CPP

1: #include <iostream.h> 2: // nh ngha s phc 3: typedef struct 4: { 5: 6: double Real; double Imaginary;

7: }Complex; 8: 9: Complex SetComplex(double R,double I);

10: void DisplayComplex(Complex C); 11: Complex operator + (Complex C1,Complex C2); 12: Complex operator - (Complex C1,Complex C2); 13: 14: int main(void) 15: { 16: 17: 18: 19: 20: 21: 22: 23: C1 = SetComplex(1.0,2.0); C2 = SetComplex(-3.0,4.0); cout<<"\nSo phuc thu nhat:"; DisplayComplex(C1); cout<<"\nSo phuc thu hai:"; DisplayComplex(C2); Complex C1,C2,C3,C4;

45

24: 25: 26: 27: 28: 29: 30: 31: } 32:

C3 = C1 + C2; C4 = C1 - C2; cout<<"\nTong hai so phuc nay:"; DisplayComplex(C3); cout<<"\nHieu hai so phuc nay:"; DisplayComplex(C4); return 0;

33: //t gi tr cho mt s phc 34: Complex SetComplex(double R,double I) 35: { 36: 37: 38: 39: 40: 41: } 42: 43: //Cng hai s phc 44: Complex operator + (Complex C1,Complex C2) 45: { 46: 47: 48: 49: 50: Tmp.Real = C1.Real+C2.Real; Tmp.Imaginary = C1.Imaginary+C2.Imaginary; return Tmp; Complex Tmp; Tmp.Real = R; Tmp.Imaginary = I; return Tmp; Complex Tmp;

46

51: } 52: 53: //Tr hai s phc 54: Complex operator - (Complex C1,Complex C2) 55: { 56: 57: 58: 59: 60: 61: } 62: 63: //Hin th s phc 64: void DisplayComplex(Complex C) 65: { 66: 67: } cout<<"("<<C.Real<<","<<C.Imaginary<<")"; Tmp.Real = C1.Real-C2.Real; Tmp.Imaginary = C1.Imaginary-C2.Imaginary; return Tmp; Complex Tmp;

Chng ta chy v d 2.18, kt qu hnh 2.21

Hnh 2.21: Kt qu ca v d 2.18 Nh vy trong C++, cc php ton trn cc gi tr kiu s phc c thc hin bng cc ton t ton hc chun ch khng phi bng cc tn hm nh trong C. Chng hn chng ta c lnh sau: C4 = AddComplex(C3, SubComplex(C1,C2)); 47

th trong C++, chng ta c lnh tng ng nh sau: C4 = C3 + C1 - C2; Chng ta nhn thy rng c hai lnh u cho cng kt qu nhng lnh ca C++ th d hiu hn. C++ lm c iu ny bng cch to ra cc hm nh ngha cch thc hin ca mt ton t cho cc kiu d liu t nh ngha. Mt hm nh ngha mt ton t c c php sau: data_type operator operator_symbol ( parameters ) { } Trong : data_type: Kiu tr v. operator_symbol: K hiu ca ton t. parameters: Cc tham s (nu c). Trong chng trnh v d 2.18, ton t + l ton t gm hai ton hng (gi l ton t hai ngi; ton t mt ngi l ton t ch c mt ton hng) v trnh bin dch bit tham s u tin l bn tri ton t, cn tham s th hai th bn phi ca ton t. Trong trng hp lp trnh vin quen thuc vi cch gi hm, C++ vn cho php bng cch vit nh sau: C3 = operator + (C1,C2); C4 = operator - (C1,C2); Cc ton t c a nng ha s c la chn bi trnh bin dch cng theo cch thc tng t nh vic chn la gia cc hm c a nng ha l khi gp mt ton t lm vic trn cc kiu khng phi l kiu c sn, trnh bin dch s tm mt hm nh ngha ca ton t no c cc tham s i snh vi cc ton hng dng. Chng ta s tm hiu k v vic a nng ha cc ton t trong chng 4. Cc gii hn ca a nng ha ton t: Chng ta khng th nh ngha cc ton t mi. Hu ht cc ton t ca C++ u c th c a nng ha. Cc ton t sau khng c a nng ha l : Ton t :: Ton t nh phm vi. 48 ngha

.* . ?: sizeof

Truy cp n con tr l trng ca struct hay thnh vin ca class. Truy cp n trng ca struct hay thnh vin ca class. Ton t iu kin

v chng ta cng khng th a nng ha bt k k hiu tin x l no. Chng ta khng th thay i th t u tin ca mt ton t hay khng th thay i s cc ton hng ca n. Chng ta khng th thay i ngha ca cc ton t khi p dng cho cc kiu c sn. a nng ha cc ton t khng th c cc tham s c gi tr mc nh. Cc ton t c th a nng ho: + ! ^= <= () ~ != = &= >= [] *= , * < |= && new /= -> / > << || delete %= ->* % += >> ++ & >>= ^ -= <<= -| ==

Cc ton t c phn loi nh sau : Cc ton t mt ngi : * & ~ ! ++ -- sizeof (data_type) Cc ton t ny c nh ngha ch c mt tham s v phi tr v mt gi tr cng kiu vi tham s ca chng. i vi ton t sizeof phi tr v mt gi tr kiu size_t (nh ngha trong stddef.h) Ton t (data_type) c dng chuyn i kiu, n phi tr v mt gi tr c kiu l data_type. 49

Cc ton t hai ngi: * / % + - >> << > < >= <= == != & | ^ && || Cc ton t ny c nh ngha c hai tham s. Cc php gn: = += -= *= /= %= >>= <<= ^= |= Cc ton t gn c nh ngha ch c mt tham s. Khng c gii hn v kiu ca tham s v kiu tr v ca php gn. Ton t ly thnh vin : -> Ton t ly phn t theo ch s: [] Ton t gi hm: ()

3.1 DN NHP
By gi chng ta bt u tm hiu v lp trnh hng i tng trong C++. Trong cc phn sau, chng ta cng tm hiu v cc k thut ca thit k hng i tng (Object-Oriented Design OOD): Chng ta phn tch mt vn c th, xc nh cc i tng no cn ci t h thng, xc nh cc thuc tnh no m i tng phi c, xc nh hnh vi no m i tng cn a ra, v ch r lm th no cc i tng cn tng tc vi i tng khc thc hin cc mc tiu tng th ca h thng. Chng ta nhc li cc khi nim v thut ng chnh ca nh hng i tng. OOP ng gi d liu (cc thuc tnh) v cc hm (hnh vi) thnh gi gi l cc i tng. D liu v cc hm ca i tng c s lin h mt thit vi nhau. Cc i tng c cc c tnh ca vic che du thng tin. iu ny ngha l mc d cc i tng c th bit lm th no lin lc vi i tng khc thng qua cc giao din hon ton xc nh, bnh thng cc i tng khng c php bit lm th no cc i tng khc c thc thi, cc chi tit ca s thi hnh c du bn trong cc i tng. Trong C v cc ngn ng lp trnh th tc, lp trnh c khuynh hng nh hng hnh ng, trong khi tng trong lp trnh C++ l nh hng i tng. Trong C, n v ca lp trnh l hm; trong C++, n v ca lp trnh l lp (class) . Cc lp trnh vin C tp trung vo vit cc hm. Cc nhm ca cc hnh ng m thc hin vi cng vic c to thnh cc hm, v cc hm c nhm thnh cc chng trnh. D liu th rt quan trng trong C, nhng quan im l d liu tn ti chnh trong vic h tr cc hm ng m hm thc hin. Cc ng t trong mt h thng gip cho lp trnh vin C xc nh tp cc hm m s hot ng cng vi vic thc thi h thng. Cc lp trnh vin C++ tp trung vo vic to ra "cc kiu do ngi dng nh ngha" (user-defined types) gi l cc lp. Cc lp cng c tham chiu nh "cc kiu do lp trnh vin nh ngha" (programmer-defined types). Mi lp cha d liu cng nh tp cc hm m x l d liu. Cc thnh phn d liu ca mt lp c gi l "cc thnh vin d liu" (data members). Cc thnh phn hm ca mt lp c gi l "cc hm thnh vin" (member functions). Ging nh thc th ca kiu c sn nh int c gi l mt bin, mt thc th ca 50

kiu do ngi dng nh ngha (ngha l mt lp) c gi l mt i tng. Cc danh t trong mt h thng gip cho lp trnh vin C++ xc nh tp cc lp. Cc lp ny c s dng to cc i tng m s s hot ng cng vi vic thc thi h thng. Cc lp trong C++ c tin ha t nhin ca khi nim struct trong C. Trc khi tin hnh vic trnh by cc lp trong C++, chng ta tm hiu v cu trc, v chng ta xy dng mt kiu do ngi dng nh ngha da trn mt cu trc.

3.2 CI T MT KIU DO NGI DNG NH NGHA VI MT STRUCT


V d 3.1: Chng ta xy dng kiu cu trc Time vi ba thnh vin s nguyn: Hour, Minute v second. Chng trnh nh ngha mt cu trc Time gi l DinnerTime. Chng trnh in thi gian di dng gi qun i v dng chun.
CT3_1.CPP

1: #include <iostream.h> 2: 3: struct Time 4: { 5: 6: 7: 8: }; 9: 10: void PrintMilitary(const Time &); //prototype 11: void PrintStandard(const Time &); //prototype 12: 13: int main() 14: { 15: 16: 17: 18: 19: //Thit lp cc thnh vin vi gi tr hp l DinnerTime.Hour = 18; DinnerTime.Minute = 30; Time DinnerTime; int Hour; // 0-23 int Minute; // 0-59 int Second; // 0-59

51

20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: }

DinnerTime.Second = 0;

cout << "Dinner will be held at "; PrintMilitary(DinnerTime); cout << " military time," << endl << "which is "; PrintStandard(DinnerTime); cout << " standard time." << endl;

//Thit lp cc thnh vin vi gi tr khng hp l DinnerTime.Hour = 29; DinnerTime.Minute = 73; DinnerTime.Second = 103;

cout << endl << "Time with invalid values: "; PrintMilitary(DinnerTime); cout << endl; return 0;

Chng ta chy v d 3.1, kt qu hnh 3.1

Hnh 3.1: Kt qu ca v d 3.1 C mt vi hn ch khi to cc kiu d liu mi vi cc cu trc phn trn. Khi vic khi to khng c yu cu, c th c d liu cha khi to v cc vn ny sinh. Ngay c nu d liu c khi to, n c th khi to khng chnh xc. Cc gi tr khng hp l c th c gn cho cc thnh vin ca mt cu trc bi v 52

chng trnh trc tip truy cp d liu. Chng hn v d 3.1 dng 29 n dng 31, chng trnh gn cc gi tr khng hp l cho i tng DinnerTime. Nu vic ci t ca struct thay i, tt c cc chng trnh s dng struct phi thay i. iu ny do lp trnh vin trc tip thao tc kiu d liu. Khng c "giao din" bo m lp trnh vin s dng d liu chnh xc v bo m d liu cn li trng thi thch hp. Mt khc, cu trc trong C khng th c in nh mt n v, chng c in khi cc thnh vin c in. Cc cu trc trong C khng th so snh vi nhau, chng phi c so snh thnh vin vi thnh vin. Phn sau ci t li cu trc Time v d 3.1 nh mt lp v chng minh mt s thun li vic to ra ci gi l cc kiu d liu tru tng (Abstract Data Types ADT) nh cc lp. Chng ta s thy rng cc lp v cc cu trc c th s dng gn nh ging nhau trong C++. S khc nhau gia chng l thuc tnh truy cp cc thnh vin.

3.2 CI T MT KIU DO NGI DNG NH NGHA VI MT STRUCT


V d 3.1: Chng ta xy dng kiu cu trc Time vi ba thnh vin s nguyn: Hour, Minute v second. Chng trnh nh ngha mt cu trc Time gi l DinnerTime. Chng trnh in thi gian di dng gi qun i v dng chun.
CT3_1.CPP

1: #include <iostream.h> 2: 3: struct Time 4: { 5: 6: 7: 8: }; 9: 10: void PrintMilitary(const Time &); //prototype 11: void PrintStandard(const Time &); //prototype 12: 13: int main() 14: { 15: 16: 17: //Thit lp cc thnh vin vi gi tr hp l Time DinnerTime; int Hour; // 0-23 int Minute; // 0-59 int Second; // 0-59

53

18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: }

DinnerTime.Hour = 18; DinnerTime.Minute = 30; DinnerTime.Second = 0;

cout << "Dinner will be held at "; PrintMilitary(DinnerTime); cout << " military time," << endl << "which is "; PrintStandard(DinnerTime); cout << " standard time." << endl;

//Thit lp cc thnh vin vi gi tr khng hp l DinnerTime.Hour = 29; DinnerTime.Minute = 73; DinnerTime.Second = 103;

cout << endl << "Time with invalid values: "; PrintMilitary(DinnerTime); cout << endl; return 0;

Chng ta chy v d 3.1, kt qu hnh 3.1

Hnh 3.1: Kt qu ca v d 3.1 54

C mt vi hn ch khi to cc kiu d liu mi vi cc cu trc phn trn. Khi vic khi to khng c yu cu, c th c d liu cha khi to v cc vn ny sinh. Ngay c nu d liu c khi to, n c th khi to khng chnh xc. Cc gi tr khng hp l c th c gn cho cc thnh vin ca mt cu trc bi v chng trnh trc tip truy cp d liu. Chng hn v d 3.1 dng 29 n dng 31, chng trnh gn cc gi tr khng hp l cho i tng DinnerTime. Nu vic ci t ca struct thay i, tt c cc chng trnh s dng struct phi thay i. iu ny do lp trnh vin trc tip thao tc kiu d liu. Khng c "giao din" bo m lp trnh vin s dng d liu chnh xc v bo m d liu cn li trng thi thch hp. Mt khc, cu trc trong C khng th c in nh mt n v, chng c in khi cc thnh vin c in. Cc cu trc trong C khng th so snh vi nhau, chng phi c so snh thnh vin vi thnh vin. Phn sau ci t li cu trc Time v d 3.1 nh mt lp v chng minh mt s thun li vic to ra ci gi l cc kiu d liu tru tng (Abstract Data Types ADT) nh cc lp. Chng ta s thy rng cc lp v cc cu trc c th s dng gn nh ging nhau trong C++. S khc nhau gia chng l thuc tnh truy cp cc thnh vin.

3.3 CI T MT KIU D LIU TRU TNG VI MT LP


Cc lp cho php lp trnh vin m hnh cc i tng m c cc thuc tnh (biu din nh cc thnh vin d liu Data members) v cc hnh vi hoc cc thao tc (biu din nh cc hm thnh vin Member functions). Cc kiu cha cc thnh vin d liu v cc hm thnh vin c nh ngha thng thng trong C++ s dng t kha class, c c php nh sau: class <class-name> { <member-list> //Thn ca lp }; Trong : class-name: tn lp. member-list: c t cc thnh vin d liu v cc hm thnh vin. Cc hm thnh vin i khi c gi l cc phng thc (methods) trong cc ngn ng lp trnh hng i tng khc, v c a ra trong vic p ng cc message gi ti mt i tng. Mt message tng ng vi vic gi hm thnh vin. Khi mt lp c nh ngha, tn lp c th c s dng khai bo i tng ca lp theo c php sau: <class-name> <object-name>; Chng hn, cu trc Time s c nh ngha di dng lp nh sau: class Time { 55

public: Time(); void SetTime(int, int, int) void PrintMilitary(); void PrintStandard() private: int Hour; // 0 - 23 int Minute; // 0 - 59 int Second; // 0 - 59 }; Trong nh ngha lp Time cha ba thnh vin d liu l Hour, Minute v Second, v cng trong lp ny, chng ta thy cc nhn public v private c gi l cc thuc tnh xc nh truy cp thnh vin (member access specifiers) gi tt l thuc tnh truy cp. Bt k thnh vin d liu hay hm thnh vin khai bo sau public c th c truy cp bt k ni no m chng trnh truy cp n mt i tng ca lp. Bt k thnh vin d liu hay hm thnh vin khai bo sau private ch c th c truy cp bi cc hm thnh vin ca lp. Cc thuc tnh truy cp lun lun kt thc vi du hai chm (:) v c th xut hin nhiu ln v theo th t bt k trong nh ngha lp. Mc nh thuc tnh truy cp l private. nh ngha lp cha cc prototype ca bn hm thnh vin sau thuc tnh truy cp public l Time(), SetTime(), PrintMilitary() v PrintStandard(). l cc hm thnh vin public (public member function) hoc giao din (interface) ca lp. Cc hm ny s c s dng bi cc client (ngha l cc phn ca mt chng trnh m l cc ngi dng) ca lp x l d liu ca lp. C th nhn thy trong nh ngha lp Time, hm thnh vin Time() c cng tn vi tn lp Time, n c gi l hm xy dng (constructor function) ca lp Time. Mt constructor l mt hm thnh vin c bit m khi ng cc thnh vin d liu ca mt i tng ca lp. Mt constructor ca lp c gi t ng khi i tng ca lp c to. Thng thng, cc thnh vin d liu c lit k trong phn private ca mt lp, cn cc hm thnh vin c lit k trong phn public. Nhng c th c cc hm thnh vin private v thnh vin d liu public. Khi lp c nh ngha, n c th s dng nh mt kiu trong phn khai bo nh sau: Time Sunset, // i tng ca lp Time ArrayTimes[5], // Mng cc i tng ca lp Time *PTime, // Con tr tr n mt i tng ca lp Time 56

&DinnerTime = Sunset; // Tham chiu n mt i tng ca lp Time V d 3.2: Xy dng li lp Time v d 3.1
CT3_2.CPP

1: #include <iostream.h> 2: 3: class Time 4: { 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: }; 15: 16: //Constructor khi to mi thnh vin d liu vi gi tr zero 17: //Bo m tt c cc i tng bt u mt trng thi thch hp 18: Time::Time() 19: { 20: Hour = Minute = Second = 0; 21: } 22: 23: //Thit lp mt gi tr Time mi s dng gi quni 24: //Thc hin vic kim tra tnh hp l trn cc gi tr d liu public: Time(); //Constructor

void SetTime(int, int, int); //Thit lp Hour, Minute va Second void PrintMilitary(); //In thi gian di dng gi qun i void PrintStandard(); //In thi gian di dng chun private: int Hour; // 0 - 23 int Minute; // 0 - 59 int Second; // 0 - 59

57

25: //Thit lp cc gi tr khng hp l thnh zero 26: void Time::SetTime(int H, int M, int S) 27: { 28: 29: 30: 31: } 32: 33: //In thi gian di dng gi qun i 34: void Time::PrintMilitary() 35: { 36: 37: 38: 39: } 40: 41: //In thi gian di dng chun 42: void Time::PrintStandard() 43: { 44: 44: 45: 46: 48: } 49: 50: int main() 51: { cout << ((Hour == 0 || Hour == 12) ? 12 : Hour % 12) << ":" << (Minute < 10 ? "0" : "") << Minute << ":" << (Second < 10 ? "0" : "") << Second << (Hour < 12 ? " AM" : " PM"); cout << (Hour < 10 ? "0" : "") << Hour << ":" << (Minute < 10 ? "0" : "") << Minute << ":" << (Second < 10 ? "0" : "") << Second; Hour = (H >= 0 && H < 24) ? H : 0; Minute = (M >= 0 && M < 60) ? M : 0; Second = (S >= 0 && S < 60) ? S : 0;

58

52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: }

Time T; //i tng T ca lp Time

cout << "The initial military time is "; T.PrintMilitary(); cout << endl << "The initial standard time is "; T.PrintStandard();

T.SetTime(13, 27, 6); cout << endl << endl << "Military time after SetTime is "; T.PrintMilitary(); cout << endl << "Standard time after SetTime is "; T.PrintStandard();

T.SetTime(99, 99, 99); //Th thit lp gi tr khng hp l cout << endl << endl << "After attempting invalid settings:" << endl << "Military time: "; T.PrintMilitary(); cout << endl << "Standard time: "; T.PrintStandard(); cout << endl; return 0;

Chng ta chy v d 3.2, kt qu hnh 3.2

59

Hnh 3.2: Kt qu ca v d 3.2 Trong v d 3.2, chng trnh thuyt minh mt i tng ca lp Time gi l T (dng 52). Khi constructor ca lp Time t ng gi v r rng khi to mi thnh vin d liu private l zero. Sau thi gian c in di dng gi qun i v dng chun xc nhn cc thnh vin ny c khi to thch hp (dng 54 n 57). K ti thi gian c thit lp bng cch s dng hm thnh vin SetTime() (dng 59) v thi gian li c in hai dng (dng 60 n 63). Cui cng hm thnh vin SetTime() (dng 65) th thit lp cc thnh vin d liu vi cc gi tr khng hp l, v thi gian li c in hai dng (dng 66 n 70). Chng ta nhn thy rng, tt c cc thnh vin d liu ca mt lp khng th khi to ti ni m chng c khai bo trong thn lp. Cc thnh vin d liu ny phi c khi to bi constructor ca lp hay chng c th gn gi tr bi cc hm thit lp. Khi mt lp c nh ngha v cc hm thnh vin ca n c khai bo, cc hm thnh vin ny phi c nh ngha. Mi hm thnh vin ca lp c th c nh ngha trc tip trong thn lp (hin nhin bao gm prototype hm ca lp), hoc hm thnh vin c th c nh ngha sau thn lp. Khi mt hm thnh vin c nh ngha sau nh ngha lp tng ng, tn hm c t trc bi tn lp v ton t nh phm vi (::). Chng hn nh v d 3.2 gm cc dng 18, 26, 34 v 42. Bi v cc lp khc nhau c th c cc tn thnh vin ging nhau, ton t nh phm vi "rng buc" tn thnh vin ti tn lp nhn dng cc hm thnh vin ca mt lp. Mc d mt hm thnh vin khai bo trong nh ngha mt lp c th nh ngha bn ngoi nh ngha lp ny, hm thnh vin vn cn bn trong phm vi ca lp, ngha l tn ca n ch c bit ti cc thnh vin khc ca lp ngoi tr tham chiu thng qua mt i tng ca lp, mt tham chiu ti mt i tng ca lp, hoc mt con tr tr ti mt i tng ca lp. Nu mt hm thnh vin c nh ngha trong nh ngha mt lp, hm thnh vin ny chnh l hm inline. Cc hm thnh vin nh ngha bn ngoi nh ngha mt lp c th l hm inline bng cch s dng t kha inline. Hm thnh vin cng tn vi tn lp nhng t trc l mt k t ng (~) c gi l destructor ca lp ny. Hm destructor lm "cng vic ni tr kt thc" trn mi i tng ca lp trc khi vng nh cho i tng c phc hi bi h thng. V d 3.3: Ly li v d 3.2 nhng hai hm PrintMilitary() v PrintStandard() l cc hm inline.
A.CPP

60

1: #include <iostream.h> 2: 3: class Time 4: { 5: public: 6: Time(); ; //Constructor 7: void SetTime(int, int, int); // Thit lp Hour, Minute va Second 8: void PrintMilitary() // In thi gian di dng gi quni 9: { 10: cout << (Hour < 10 ? "0" : "") << Hour << ":" 11: 12: 13: } 14: void PrintStandard(); // In thi gian di dng chun 15: private: 16: int Hour; // 0 - 23 17: int Minute; // 0 - 59 18: int Second; // 0 - 59 19: }; 20: //Constructor khi to mi thnh vin d liu vi gi tr zero 21: //Bo m tt c cc i tng bt u mt trng thi thch hp 22: Time::Time() 23: { 24: Hour = Minute = Second = 0; 25: } 26: << (Minute < 10 ? "0" : "") << Minute << ":" << (Second < 10 ? "0" : "") << Second;

61

27: #9; //Thit lp mt gi tr Time mi s dng gi qun i 28: #9; //Thc hin vic kim tra tnh hp l trn cc gi tr d liu 29: #9; //Thit lp cc gi tr khng hp l thnh zero 30: void Time::SetTime(int H, int M, int S) 31: { 32: Hour = (H >= 0 && H < 24) ? H : 0; 33: Minute = (M >= 0 && M < 60) ? M : 0; 34: Second = (S >= 0 && S < 60) ? S : 0; 35: } 36: 37: #9; //In thi gian di dng chun 38: inline void Time::PrintStandard() 39: { 40: cout << ((Hour == 0 || Hour == 12) ? 12 : Hour % 12) 41: 42: << ":" << (Minute < 10 ? "0" : "") << Minute << ":" << (Second < 10 ? "0" : "") << Second

43: << (Hour < 12 ? " AM" : " PM"); 44: } 45: 46: int main() 47: { 48: Time T; 49: 50: cout << "The initial military time is "; 51: T.PrintMilitary(); 52: cout << endl << "The initial standard time is ";

62

53: T.PrintStandard(); 54: 55: T.SetTime(13, 27, 6); 56: cout << endl << endl << "Military time after SetTime is "; 57: T.PrintMilitary(); 58: cout << endl << "Standard time after SetTime is "; 59: T.PrintStandard(); 60: 61: T.SetTime(99, 99, 99); //Th thit lp gi tr khng hp l 62: cout << endl << endl << "After attempting invalid settings:" 63: << endl << "Military time: ";

64: T.PrintMilitary(); 65: cout << endl << "Standard time: "; 66: T.PrintStandard(); 67: cout << endl; 68: return 0; 69: }

Chng ta chy v d 3.3, kt qu hnh 3.3

Hnh 3.3: Kt qu ca v d 3.3 63

3.4 PHM VI LP V TRUY CP CC THNH VIN LP


Cc thnh vin d liu ca mt lp (cc bin khai bo trong nh ngha lp) v cc hm thnh vin (cc hm khai bo trong nh ngha lp) thuc vo phm vi ca lp. Trong mt phm vi lp, cc thnh vin ca lp c truy cp ngay lp tc bi tt c cc hm thnh vin ca lp v c th c tham chiu mt cch d dng bi tn. Bn ngoi mt phm vi lp, cc thnh vin ca lp c tham chiu thng qua hoc mt tn i tng, mt tham chiu n mt i tng, hoc mt con tr ti i tng. Cc hm thnh vin ca lp c th c a nng ha (overload), nhng ch bi cc hm thnh vin khc ca lp. a nng ha mt hm thnh vin, n gin cung cp trong nh ngha lp mt prototype cho mi phin bn ca hm a nng ha, v cung cp mt nh ngha hm ring bit cho mi phin bn ca hm. Cc hm thnh vin c phm vi hm trong mt lp cc bin nh ngha trong mt hm thnh vin ch c bit ti hm . Nu mt hm thnh vin nh ngha mt bin cng tn vi tn mt bin trong phm vi lp, bin phm vi lp c du bi bin phm vi hm bn trong phm vi hm. Nh th mt bin b du c th c truy cp thng qua ton t nh phm vi. Cc ton t c s dng truy cp cc thnh vin ca lp c ng nht vi cc ton t s dng truy cp cc thnh vin ca cu trc. Ton t la chn thnh vin du chm (.) c kt hp vi mt tn ca i tng hay vi mt tham chiu ti mt i tng truy cp cc thnh vin ca i tng. Ton t la chn thnh vin mi tn (->)c kt hp vi mt con tr tr ti mt truy cp truy cp cc thnh vin ca i tng. V d 3.4: Chng trnh sau minh ha vic truy cp cc thnh vin ca mt lp vi cc ton t la chn thnh vin.
CT3_4.CPP

1: #include <iostream.h> 2: 3: class Count 4: { 5: 6: 7: 8: 9: 10: 11: }; } public: int X; void Print() { cout << X << endl;

64

12: 13: int main() 14: { 15: 16: 17: 18: 19: "; 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: } cout << "Assign 10 to X and Print using a pointer: "; CounterPtr->X = 10; // Gn 10 cho thnh vin d liu X CounterPtr->Print(); //Gi hm thnh vin Print return 0; cout << "Assign 8 to X and Print using a reference: "; CounterRef.X = 8; //Gn 8 cho thnh vin d liu X CounterRef.Print(); //Gi hm thnh vin Print cout << "Assign 7 to X and Print using the object's name: Count Counter, //To i tng Counter *CounterPtr = &Counter, //Con tr tr ti Counter &CounterRef = Counter; //Tham chiu ti Counter

Counter.X = 7; //Gn 7 cho thnh vin d liu X Counter.Print(); //Gi hm thnh vin Print

Chng ta chy v d 3.4, kt qu hnh 3.4

Hnh 3.4: Kt qu ca v d 3.4 65

3.5 IU KHIN TRUY CP TI CC THNH VIN


Cc thuc tnh truy cp public v private (v protected chng ta s xem xt sau) c s dng iu khin truy cp ti cc thnh vin d liu v cc hm thnh vin ca lp. Ch truy cp mc nh i vi lp l private v th tt c cc thnh vin sau phn header ca lp v trc nhn u tin l private. Sau mi nhn, ch m c ko theo bi nhn p dng cho n khi gp nhn k tip hoc cho n khi gp du mc phi (}) ca phn nh ngha lp. Cc nhn public, private v protected c th c lp li nhng cch dng nh vy th him c v c th gy kh hiu. Cc thnh vin private ch c th c truy cp bi cc hm thnh vin (v cc hm friend) ca lp . Cc thnh vin public ca lp c th c truy cp bi bt k hm no trong chng trnh. Mc ch chnh ca cc thnh vin public l biu th cho client ca lp mt ci nhn ca cc dch v (services) m lp cung cp. Tp hp ny ca cc dch v hnh thnh giao din public ca lp. Cc client ca lp khng cn quan tm lm th no lp hon thnh cc thao tc ca n. Cc thnh vin private ca lp cng nh cc nh ngha ca cc hm thnh vin public ca n th khng phi c th truy cp ti client ca mt lp. Cc thnh phn ny hnh thnh s thi hnh ca lp. V d 3.5: Chng trnh sau cho thy rng cc thnh vin private ch c th truy cp thng qua giao din public s dng cc hm thnh vin public.
CT3_5.CPP

1: #include <iostream.h> 2: 3: class MyClass 4: { 5: private: 6: int X,Y; 7: public: 8: void Print(); 9: }; 10: 11: void MyClass::Print() 12: { 13: cout <<X<<Y<<endl; 14: } 15:

66

16: int main() 17: { 18: MyClass M; 19: 20: M.X = 3; //Error: 'MyClass::X' is not accessible 21: M.Y = 4; //Error: 'MyClass::Y' is not accessible 22: M.Print(); 23: return 0; 24: }

Khi chng ta bin dch chng trnh ny, compiler pht sinh ra hai li ti hai dng 20 v 21 nh sau:

Hnh 3.5: Thng bo li ca v d 3.5 Thuc tnh truy cp mc nh i vi cc thnh vin ca lp l private. Thuc tnh truy cp cc thnh vin ca mt lp c th c thit lp r rng l public, protected hoc private. Thuc tnh truy cp mc nh i vi cc thnh vin ca struct l public. Thuc tnh truy cp cc thnh vin ca mt struct cng c th c thit lp r rng l public, protected hoc private. Truy cp n mt d liu private cn phi c iu khin cn thn bi vic s dng ca cc hm thnh vin, gi l cc hm truy cp (access functions).

3.6 CC HM TRUY CP V CC HM TIN CH


Khng phi tt c cc hm thnh vin u l public phc v nh b phn giao din ca mt lp. Mt vi hm cn li l private v phc v nh cc hm tin ch (utility functions) cho cc hm khc ca lp. Cc hm truy cp c th c hay hin th d liu. S dng cc hm truy cp kim tra tnh ng hoc sai ca cc iu kin cc hm nh th thng c gi l cc hm khng nh (predicate functions). Mt v d ca hm khng nh l mt hm IsEmpty() ca lp container - mt lp c kh nng gi nhiu i tng - ging nh mt danh sch lin kt, mt stack hay mt hng i. Mt chng trnh s kim tra hm IsEmpty() trc khi th c mc khc t i tng container.Mt hm tin ch khng l mt phn ca mt giao din ca lp. Hn na n l mt hm thnh vin private m h tr cc thao tc ca cc hm thnh vin public. Cc hm tin ch khng d nh c s dng bi cc client ca lp. V d 3.6: Minh ha cho cc hm tin ch. 67

CT3_6.CPP

1: #include <iostream.h> 2: #include <iomanip.h> 3: 4: class SalesPerson 5: { 6: public: 7: SalesPerson(); //constructor

8: void SetSales(int, double);//Ngi dng cung cp cc hnh ca 9: thng 10: void PrintAnnualSales(); 11: 12: private: 13: double Sales[12]; //12 hnh ca nhng hng bn hng thng 14: double TotalAnnualSales(); //Hm tin ch 15: }; 16: 17: //Hm constructor khi to mng 18: SalesPerson::SalesPerson() 19: { 20: for (int I = 0; I < 12; I++) 21: Sales[I] = 0.0; 22: } 23: 24: //Hm thit lp mt trong 12 hnh ca nhng hng bn hng thng 25: void SalesPerson::SetSales(int Month, double Amount) 26: { #9; #9; //nhng hng bn ca mt

68

27: if (Month >= 1 && Month <= 12 && Amount > 0) 28: Sales[Month - 1] = Amount; 29: else 30: cout << "Invalid month or sales figure" << endl; 31: } 32: 33: //Hm tin ch tnh tng hng bn hng nm 34: double SalesPerson::TotalAnnualSales() 35: { 36: double Total = 0.0; 37: 38: for (int I = 0; I < 12; I++) 39: Total += Sales[I]; 40: return Total; 41: } 42: 43: //In tng hng bn hng nm 44: void SalesPerson::PrintAnnualSales() 45: { 46: cout << setprecision(2) 47: 48: 49: 50: } 51: 52: int main() 53: { << setiosflags(ios::fixed | ios::showpoint) << endl << "The total annual sales are: $" << TotalAnnualSales() << endl;

69

54: SalesPerson S; 55: double salesFigure; 56: 57: for (int I = 1; I <= 12; I++) 58: { 59: cout << "Enter sales amount for month "<< I << ": "; 60: cin >> salesFigure; 61: S.SetSales(I, salesFigure); 62: } 63: S.PrintAnnualSales(); 64: return 0; 65: }

Chng ta chy v d 3.6 , kt qu hnh 3.6

Hnh 3.6: Kt qu ca v d 3.6

3.7 KHI NG CC I TNG CA LP : CONSTRUCTOR


70

Khi mt i tng c to, cc thnh vin ca n c th c khi to bi mt hm constructor. Mt constructor l mt hm thnh vin vi tn ging nh tn ca lp. Lp trnh vin cung cp constructor m c gi t ng mi khi i tng ca lp c to. Cc thnh vin d liu ca mt lp khng th c khi to trong nh ngha ca lp. Hn na, cc thnh vin d liu phi c khi ng hoc trong mt constructor ca lp hoc cc gi tr ca chng c th c thit lp sau sau khi i tng c to. Cc constructor khng th m t cc kiu tr v hoc cc gi tr tr v. Cc constructor c th c a nng ha cung cp s a dng khi to cc i tng ca lp. Constructor c th cha cc tham s mc nh. Bng cch cung cp cc tham s mc nh cho constructor, ngay c nu khng c cc gi tr no c cung cp trong mt constructor th i tng vn c bo m trong mt trng thi ph hp v cc tham s mc nh. Mt constructor ca lp trnh vin cung cp m hoc tt c cc tham s ca n c gi tr mc nh hoc khng c tham s no c gi l constructor mc nh (default constructor). Ch c th c mt constructor mc nh cho mi lp. V d 3.7: Constructor vi cc tham s mc nh
CT3_7.CPP

1: #include <iostream.h> 2: 3: class Time 4: { 5: public: 6: Time(int = 0, int = 0, int = 0); //Constructor mc nh 7: void SetTime(int, int, int); 8: void PrintMilitary(); 9: void PrintStandard(); 10: 11: private: 12: int Hour; 13: int Minute; 14: int Second; 15: }; 16: 17: //Hm constructor khi ng d liu private 18: //Cc gi tr mc nh l 0 19: Time::Time(int Hr, int Min, int Sec)

71

20: { 21: SetTime(Hr, Min, Sec); 22: } 23: 24: //Thit lp cc gi tr ca Hour, Minute v Second 25: //Gi tr khng hp l c thit lp l 0 26: void Time::SetTime(int H, int M, int S) 27: { 28: Hour = (H >= 0 && H < 24) ? H : 0; 29: Minute = (M >= 0 && M < 60) ? M : 0; 30: Second = (S >= 0 && S < 60) ? S : 0; 31: } 32: 33: //Hin th thi gian theo dng gi qun i: HH:MM:SS 34: void Time::PrintMilitary() 35: { 36: cout << (Hour < 10 ? "0" : "") << Hour << ":" 37: 38: 39: } 40: 41: // Hin th thi gian theo dng chun: HH:MM:SS AM (hoc PM) 42: void Time::PrintStandard() 43: { 44: cout << ((Hour == 0 || Hour == 12) ? 12 : Hour % 12) 45: 46: << ":" << (Minute < 10 ? "0" : "") << Minute << ":" << (Second < 10 ? "0" : "") << Second << (Minute < 10 ? "0" : "") << Minute << ":" << (Second < 10 ? "0" : "") << Second;

72

47: 48: } 49:

<< (Hour < 12 ? " AM" : " PM");

50: int main() 51: { 52: Time T1,T2(2),T3(21,34),T4(12,25,42),T5(27,74,99); 53: 54: cout << "Constructed with:" << endl 55: << "all arguments defaulted:" << endl << " ";

56: T1.PrintMilitary(); 57: cout << endl << " "; 58: T1.PrintStandard(); 59: cout << endl << "Hour specified; Minute and Second defaulted:" 60: << endl << " "; 61: T2.PrintMilitary(); 62: cout << endl << " "; 63: T2.PrintStandard(); 64: cout << endl << "Hour and Minute specified; Second defaulted:" 65: << endl << " "; 66: T3.PrintMilitary(); 67: cout << endl << " "; 68: T3.PrintStandard(); 69: cout << endl << "Hour, Minute, and Second specified:" 70: << endl << " "; 71: T4.PrintMilitary(); 72: cout << endl << " ";

73

73: T4.PrintStandard(); 74: cout << endl << "all invalid values specified:" 75: << endl << " "; 76: T5.PrintMilitary(); 77: cout << endl << " "; 78: T5.PrintStandard(); 79: cout << endl; 80: return 0; 81: }

Chng trnh v d 3.7 khi to nm i tng ca lp Time ( dng 52). i tng T1 vi ba tham s ly gi tr mc nh, i tng T2 vi mt tham s c m t, i tng T3 vi hai tham s c m t, i tng T4 vi ba tham s c m t v i tng T5 vi cc tham s c gi tr khng hp l. Chng ta chy v d 3.7, kt qu hnh 3.7

Hnh 3.7: Kt qu ca v d 3.7 Nu khng c constructor no c nh ngha trong mt lp th trnh bin dch to mt constructor mc nh. Constructor ny khng thc hin bt k s khi to no, v vy khi i tng c to, n khng bo m trong mt trng thi ph hp. 74

3.8 S DNG DESTRUCTOR


Mt destructor l mt hm thnh vin c bit ca mt lp. Tn ca destructor i vi mt lp l k t ng (~) theo sau bi tn lp. Destructor ca mt lp c gi khi i tng c hy b ngha l khi s thc hin chng trnh ri khi phm vi m trong i tng ca lp c khi to. Destructor khng thc s hy b i tng n thc hin "cng vic ni tr kt thc" trc khi h thng phc hi khng gian b nh ca i tng n c th c s dng gi cc i tng mi.Mt destructor khng nhn cc tham s v khng tr v gi tr. Mt lp ch c duy nht mt destructor a nng ha destructor l khng cho php. Nu trong mt lp khng c nh ngha mt destructor th trnh bin dch s to mt destructor mc nh khng lm g c. V d 3.8: Lp c hm destructor
CT3_8.CPP

1: #include <iostream.h> 2: 3: class Simple 4: { 5: private: 6: int *X; 7: public: 8: Simple(); //Constructor 9: ~Simple(); //Destructor 10: void SetValue(int V); 11: int GetValue(); 12: }; 13: 14: Simple::Simple() 15: { 16: X = new int; //Cp pht vng nh cho X 17: } 18: 19: Simple::~Simple() 20: {

75

21: delete X; //Gii phng vng nh khi i tng b hy b. 22: } 23: 24: void Simple::SetValue(int V) 25: { 26: *X = V; 27: } 28: 29: int Simple::GetValue() 30: { 31: return *X; 32: } 33: 34: int main() 35: { 36: Simple S; 37: int X; 38: 39: cout<<"Enter a number:"; 40: cin>>X; 41: S.SetValue(X); 42: cout<<"The value of this number:"<<S.GetValue(); 43: return 0; 44: }

Chng ta chy v d 3.8, kt qu hnh 3.8

76

Hnh 3.8: Kt qu ca v d 3.8

3.9 KHI NO CC CONSTRUTOR V DESTRUCTOR C GI ?


Cc constructor v destructor c gi mt cch t ng. Th t cc hm ny c gi ph thuc vo th t trong s thc hin vo v ri khi phm vi m cc i tng c khi to. Mt cch tng qut, cc destructor c gi theo th t ngc vi th t ca cc constructor c gi.Cc constructor c gi ca cc i tng khai bo trong phm vi ton cc trc bt k hm no (bao gm hm main()) trong file m bt u thc hin. Cc destructor tng ng c gi khi hm main() kt thc hoc hm exit() c gi.Cc constructor ca cc i tng cc b t ng c gi khi s thc hin n im m cc i tng c khai bo. Cc destructor tng ng c gi khi cc i tng ri khi phm vi (ngha l khi m trong chng c khai bo). Cc constructor v destructor i vi cc i tng cc b t ng c gi mi khi cc i tng vo v ri khi phm vi.Cc constructor c gi ca cc i tng cc b tnh (static) khi s thc hin n im m cc i tng c khai bo ln u tin. Cc destructor tng ng c gi khi hm main() kt thc hoc hm exit() c gi. V d 3.9: Chng trnh sau minh ha th t cc constructor v destructor c gi.
CT3_9.CPP

1: #include <iostream.h> 2: 3: class CreateAndDestroy 4: { 5: public: 6: CreateAndDestroy(int); //Constructor 7: ~CreateAndDestroy(); //Destructor 8: private: 9: int Data; 10: }; 11: 12: CreateAndDestroy::CreateAndDestroy(int Value) 13: { 14: Data = Value;

77

15: cout << "Object " << Data << " constructor"; 16: } 17: 18: CreateAndDestroy::~CreateAndDestroy() 19: { 20: cout << "Object " << Data << " destructor " << endl; 21: } 22: 23: void Create(void); //Prototype 24: CreateAndDestroy First(1); //i tng ton cc 25: 26: int main() 27: { 28: cout << " (global created before main)" << endl; 29: 30: CreateAndDestroy Second(2); // i tng cc b 31: cout << " (local automatic in main)" << endl; 32: 33: static CreateAndDestroy Third(3); //i tng cc b 34: cout << " (local static in main)" << endl; 35: 36: Create(); //Gi hm to cc i tng 37: 38: CreateAndDestroy Fourth(4); //i tng cc b 39: cout << " (local automatic in main)" << endl; 40: return 0; 41: }

78

42: 43: //Hm to cci tng 44: void Create(void) 45: { 46: CreateAndDestroy Fifth(5); 47: cout << " (local automatic in create)" << endl; 48: 49: static CreateAndDestroy Sixth(6); 50: cout << " (local static in create)" << endl; 51: 52: CreateAndDestroy Seventh(7); 53: cout << " (local automatic in create)" << endl; 54: }

Chng trnh khai bo First phm vi ton cc. Constructor ca n c gi khi chng trnh bt u thc hin v destructor ca n c gi lc chng trnh kt thc sau tt c cc i tng khc c hy b. Hm main() khai bo ba i tng. Cc i tng Second v Fourth l cc i tng cc b t ng v i tng Third l mt i tng cc b tnh. Cc constructor ca cc i tng ny c gi khi chng trnh thc hin n im m mi i tng c khai bo. Cc destructor ca cc i tng Fourth v Second c gi theo th t ny khi kt thc ca main() t n. V i tng Third l tnh, n tn ti cho n khi chng trnh kt thc. Destructor ca i tng Third c gi trc destructor ca First nhng sau tt c cc i tng khc c hy b. Hm Create() khai bo ba i tng Fifth v Seventh l cc i tng cc b t ng v Sixth l mt i tng cc b tnh. Cc destructor ca cc i tng Seventh v Fifth c gi theo th t ny khi kt thc ca create() t n. V i tng Sixth l tnh, n tn ti cho n khi chng trnh kt thc. Destructor ca i tng Sixth c gi trc cc destructor ca Third v First nhng sau tt c cc i tng khc c hy b. Chng ta chy v d 3.9, kt qu hnh 3.9

79

Hnh 3.9: Kt qu ca v d 3.9

3.10 S DNG CC THNH VIN D LIU V CC HM THNH VIN


Cc thnh vin d liu private ch c th c x l bi cc hm thnh vin (hay hm friend) ca lp. Cc lp thng cung cp cc hm thnh vin public cho php cc client ca lp thit lp (set) (ngha l "ghi") hoc ly (get) (ngha l "c") cc gi tr ca cc thnh vin d liu private. Cc hm ny thng khng cn phi c gi "set" hay "get", nhng chng thng t tn nh vy. Chng hn, mt lp c thnh vin d liu private c tn InterestRate, hm thnh vin thit lp gi tr c tn l SetInterestRate() v hm thnh vin ly gi tr c tn l GetInterestRate(). Cc hm "Get" cng thng c gi l cc hm cht vn (query functions). Nu mt thnh vin d liu l public th thnh vin d liu c th c c hoc ghi ti bt k hm no trong chng trnh. Nu mt thnh vin d liu l private, mt hm "get" public nht nh cho php cc hm khc c d liu nhng hm get c th iu khin s nh dng v hin th ca d liu. Mt hm "set" public c th s xem xt cn thn bt k c gng no thay i gi tr ca thnh vin d liu. iu ny s bo m rng gi tr mi th tng thch i vi mc d liu. Chng hn, mt s c gng thit lp ngy ca thng l 37 s b loi tr. Cc li ch ca s ton vn d liu th khng t ng n gin bi v cc thnh vin d liu c to l private lp trnh vin phi cung cp s kim tra hp l. Tuy nhin C++ cung cp mt khung lm vic trong cc lp trnh vin c th thit k cc chng trnh tt hn. Client ca lp phi c thng bo khi mt s c gng c to ra gn mt gi tr khng hp l cho mt thnh vin d liu. Chnh v l do ny, cc hm "set" ca lp thng c vit tr v cc gi tr cho bit rng mt s c gng to ra gn mt d liu khng hp l cho mt i tng ca lp. iu ny cho php cc client ca lp kim tra cc gi tr tr v xc nh nu i tng m chng thao tc l mt i tng hp l v bt gi hot ng thch hp nu i tng m chng thao tc th khng phi hp l. V d 3.10: Chng trnh m rng lp Time v d 3.2 bao gm hm get v set i vi cc thnh vin d liu private l hour, minute v second.
CT3_10.CPP

1: #include <iostream.h>

80

2: 3: class Time 4: { 5: public: 6: Time(int = 0, int = 0, int = 0); //Constructor 7: //Cc hm set 8: void SetTime(int, int, int); //Thit lp Hour, Minute, Second 9: void SetHour(int); //Thit lp Hour 10: void SetMinute(int); //Thit lp Minute 11: void SetSecond(int); //Thit lp Second 12: //Cc hm get 13: int GetHour(); 14: int GetMinute(); 15: int GetSecond(); 16: 17: void PrintMilitary(); //Xut thi gian theo dng gi quni 18: void PrintStandard(); //Xut thi gian theo dng chun 19: 20: private: 21: int Hour; //0 - 23 22: int Minute; //0 - 59 23: int Second; //0 59 24: }; 25: 26: //Constructor khing d liu private 27: //Gi hm thnh vin SetTime() thit lp cc bin 24: //Cc gi tr mc nh l 0 //Tr v Hour //Tr v Minute //Tr v Second

81

25: Time::Time(int Hr, int Min, int Sec) 26: { 27: SetTime(Hr, Min, Sec); 28: } 29: 30: //Thit lp cc gi tr ca Hour, Minute, v Second 31: void Time::SetTime(int H, int M, int S) 32: { 33: Hour = (H >= 0 && H < 24) ? H : 0; 34: Minute = (M >= 0 && M < 60) ? M : 0; 35: Second = (S >= 0 && S < 60) ? S : 0; 36: } 37: 38: //Thit lp gi tr ca Hour 39: void Time::SetHour(int H) 40: { 41: Hour = (H >= 0 && H < 24) ? H : 0; 42: } 43: 44: //Thit lp gi tr ca Minute 45: void Time::SetMinute(int M) 46: { 47: Minute = (M >= 0 && M < 60) ? M : 0; 48: } 49: 50: //Thit lp gi tr ca Second 51: void Time::SetSecond(int S)

82

52: { 53: Second = (S >= 0 && S < 60) ? S : 0; 54: } 55: 56: //Ly gi tr ca Hour 57: int Time::GetHour() 58: { 59: return Hour; 60: } 61: 62: //Ly gi tr ca Minute 63: int Time::GetMinute() 64: { 65: return Minute; 66: } 67: 68: //Ly gi tr ca Second 69: int Time::GetSecond() 70: { 71: return Second; 72: } 73: 74: //Hin th thi gian dng gi quni: HH:MM:SS 75: void Time::PrintMilitary() 76: { 77: cout << (Hour < 10 ? "0" : "") << Hour << ":" 78: << (Minute < 10 ? "0" : "") << Minute << ":"

83

79: 80: } 81:

<< (Second < 10 ? "0" : "") << Second;

83: //Hin th thi gian dng chun: HH:MM:SS AM (hay PM) 84: void Time::PrintStandard() 85: { 86: cout << ((Hour == 0 || Hour == 12) ? 12 : Hour % 12) << ":" 87: 88: 89: 90: } 91: 92: void IncrementMinutes(Time &, const int); //prototype 93: 94: int main() 95: { 96: Time T; 97: 99: T.SetHour(17); 100: T.SetMinute(34); 101: T.SetSecond(25); 102 cout << "Result of setting all valid values:" << endl 103: 104: 105: << " Hour: " << T.GetHour() << " Minute: " << T.GetMinute() << " Second: " << T.GetSecond() << endl << endl; << (Minute < 10 ? "0" : "") << Minute << ":" << (Second < 10 ? "0" : "") << Second << (Hour < 12 ? " AM" : " PM");

106: T.SetHour(234); //Hour khng hp lc thit lp bng 0 107: T.SetMinute(43);

84

108: T.SetSecond(6373); //Second khng hp lc thit lp bng 0 109: cout << "Result of attempting to set invalid Hour and" 110: 111: 112: << " Second:" << endl << " Hour: " << T.GetHour() << " Minute: " << T.GetMinute() << " Second: " << T.GetSecond() << endl << endl;

113: T.SetTime(11, 58, 0); 114: IncrementMinutes(T, 3); 115: return 0; 116: } 117: 118: void IncrementMinutes(Time &TT, const int Count) 119: { 120: cout << "Incrementing Minute " << Count 121: << " times:" << endl << "Start time: ";

122: TT.PrintStandard(); 123: for (int I = 1; I <= Count; I++) 124: { 125: TT.SetMinute((TT.GetMinute() + 1) % 60); 126: if (TT.GetMinute() == 0) 127: TT.SetHour((TT.GetHour() + 1) % 24); 128: cout << endl << "Minute + 1: "; 129: TT.PrintStandard(); 130: } 131: cout << endl; 132: }

85

Trong v d trn chng ta c hm IncrementMinutes() l hm dng tng Minite. y l hm khng thnh vin m s dng cc hm thnh vin get v set tng thnh vin Minite. Chng ta chy v d .10, kt qu hnh 3.10

Hnh 3.10: Kt qu ca v d 3.10

3.11 TR V MT THAM CHIU TI MT THNH VIN D LIU PRIVATE


Mt tham chiu ti mt i tng l mt b danh ca chnh i tng v do c th c s dng v tri ca php gn. Trong khung cnh , tham chiu to mt lvalue c chp nhn hon ton m c th nhn mt gi tr. Mt cch s dng kh nng ny (tht khng may!) l c mt hm thnh vin public ca lp tr v mt tham chiu khng const ti mt thnh vin d liu private ca lp . V d 3.11: Chng trnh sau s dng mt phin bn n gin ca lp Time minh ha tr v mt tham chiu ti mt d liu private.
CT3_11.CPP

1: #include <iostream.h> 2: 3: class Time 4: { 5: public: 6: Time(int = 0, int = 0, int = 0); 7: void SetTime(int, int, int); 8: int GetHour(); 9: int &BadSetHour(int); //Nguy him tr v tham chiu !!!

86

10: private: 11: int Hour; 12: int Minute; 13: int Second; 14: }; 15: 16: //Constructor khing d liu private 17: //Gi hm thnh vin SetTime() thit lp cc bin 18: //Cc gi tr mcnh l 0 19: Time::Time(int Hr, int Min, int Sec) 20: { 21: SetTime(Hr, Min, Sec); 22: } 23: //Thit lp cc gi tr ca Hour, Minute, v Second 24: void Time::SetTime(int H, int M, int S) 25: { 26: Hour = (H >= 0 && H < 24) ? H : 0; 27: Minute = (M >= 0 && M < 60) ? M : 0; 28: Second = (S >= 0 && S < 60) ? S : 0; 29: } 30: 31: //Ly gi tr ca Hour 32: int Time::GetHour() 33: { 34: return Hour; 35: } 36:

87

37: //KHNG NN LP TRNH THEO KIU NY !!! 38: //Tr v mt tham chiu ti mt thnh vin d liu private 39: int &Time::BadSetHour(int HH) 40: { 41: Hour = (HH >= 0 && HH < 24) ? HH : 0; 42: return Hour; //Nguy him tr v tham chiu !!! 43: } 44: 45: int main() 46: { 47: Time T; 48: int &HourRef = T.BadSetHour(20); 49: 50: cout << "Hour before modification: " << HourRef << endl; 51: HourRef = 30; //Thayi vi gi tr khng hp l 52: cout << "Hour after modification: " << T.GetHour() << endl; 53: // Nguy him: Hm tr v mt tham chiu 54: //c thc s dng nh mt lvalue 55: T.BadSetHour(12) = 74; 56: cout << endl << "*********************************" << endl 57: 58: 59: 60: << "BAD PROGRAMMING PRACTICE!!!!!!!!!" << endl << "BadSetHour as an lvalue, Hour: " << T.GetHour() << endl << "*********************************" << endl;

61: return 0; 62: }

88

Trong chng trnh hm BadSetHour() tr v mt tham chiu ti thnh vin d liu Hour. Chng ta chy v d 3.11, kt qu hnh 3.11

Hnh 3.11: Kt qu ca v d 3.11

3.12 PHP GN BI TON T SAO CHP THNH VIN MC NH


Ton t gn (=) c s dng gn mt i tng cho mt i tng khc ca cng mt kiu. Ton t gn nh th bnh thng c thc hin bi ton t sao chp thnh vin (Memberwise copy) Mi thnh vin ca mt i tng c sao chp ring r ti cng thnh vin i tng khc (Ch rng sao chp thnh vin c th pht sinh cc vn nghim trng khi s dng vi mt lp m thnh vin d liu cha vng nh cp pht ng).Cc i tng c th c truyn cho cc tham s ca hm v c th c tr v t cc hm. Nh th vic truyn v tr v c thc hin theo truyn gi tr mt sao chp ca i tng c truyn hay tr v.: V d 3.12: Chng trnh sau minh ha ton t sao chp thnh vin mc nh
CT3_12.CPP

1: #include <iostream.h> 2: 3: //Lp Date n gin 4: class Date 5: { 6: public: 7: Date(int = 1, int = 1, int = 1990); //Constructor mc nh 8: void Print(); 9: private: 10: int Month; 11: int Day; 12: int Year;

89

13: }; 14: 15: //Constructor Date n gin vi vic khng kim tra min 16: Date::Date(int m, int d, int y) 17: { 18: Month = m; 19: Day = d; 20: Year = y; 21: } 22: 23: //In Date theo dng mm-dd-yyyy 24: void Date::Print() 25: { 26: cout << Month << '-' << Day << '-' << Year; 27: } 28: 29: int main() 30: { 31: Date Date1(7, 4, 1993), Date2; //Date2 mc nh l 1/1/90 32: cout << "Date1 = "; 33: Date1.Print(); 34: cout << endl << "Date2 = "; 35: Date2.Print(); 36: Date2 = Date1; //Gn bi ton t sao chp thnh vin mc nh 37: cout << endl << endl 38: << "After default memberwise copy, Date2 = ";

39: Date2.Print();

90

40: cout << endl; 41: return 0; 42: }

Chng ta chy v d 3.12, kt qu hnh 3.12

Hnh 3.12: Kt qu ca v d 3.12

3.13 CC I TNG HNG V CC HMTHNH VIN CONST


Mt vi i tng cn c thay i v mt vi i tng th khng. Lp trnh vin c th s dng t kha const cho bit i tng khng th thay i c, v nu c c gng thay i i tng th xy ra li. Chng hn: const Time Noon(12,0,0); //Khai bo mt i tng const Cc trnh bin dch C++ lu n cc khai bo const v th cc trnh bin dch cm hon ton bt k hm thnh vin no gi cc i tng const (Mt vi trnh bin dch ch cung cp mt cnh bo). iu ny th khc nghit bi v cc client ca i tng hu nh chc chn s mun s dng cc hm thnh vin "get" khc nhau vi i tng, v tt nhin khng th thay i i tng. cung cp cho iu ny, lp trnh vin c th khai bo cc hm thnh vin const; iu ny ch c th thao tc trn cc i tng const. D nhin cc hm thnh vin const khng th thay i i tng - trnh bin dch cm iu ny. Mt hm c m t nh const khi c hai trong phn khai bo v trong phn nh ngha ca n c chn thm t kha const sau danh sch cc tham s ca hm, v trong trng hp ca nh ngha hm trc du ngoc mc tri ({) m bt u thn hm. Chng hn, hm thnh vin ca lp A no : int A::GetValue() const { return PrivateDataMember; } Nu mt hm thnh vin const c nh ngha bn ngoi nh ngha ca lp th khai bo hm v nh ngha hm phi bao gm const mi phn.Mt vn ny sinh y i vi cc constructor v destructor, mi hm thng cn thay i i tng. Khai bo const khng yu cu i vi cc constructor v destructor ca cc i tng const. Mt constructor phi c php thay i mt i tng m i tng c th c khi to thch hp. Mt destructor phi c kh nng thc hin vai tr "cng vic kt thc ni tr" trc khi i tng c hy. V d 3.13: Chng trnh sau s dng mt lp Time vi cc i tng const v cc hm thnh vin const. 91

CT3_13.CPP

1: #include <iostream.h> 2: 3: class Time 4: { 5: public: 6: Time(int = 0, int = 0, int = 0); //Constructor mc nh 7: //Cc hm set 8: void SetTime(int, int, int); //Thit lp thi gian 9: void SetHour(int); //Thit lp Hour 10: void SetMinute(int); //Thit lp Minute 11: void SetSecond(int); //Thit lp Second 12: //Cc hm get 13: int GetHour() const; //Tr v Hour 14: int GetMinute() const; //Tr v Minute 15: int GetSecond() const; //Tr v Second 16: //Cc hm in 17: void PrintMilitary() const; //In thi gian theo dng gi qun i 18: void PrintStandard() const; //In thi gian theo dng gi chun 19: private: 20: int Hour; //0 - 23 21: int Minute; //0 - 59 22: int Second; //0 59 23: }; 24: 25: //Constructor khi ng d liu private 26: //Cc gi tr mc nh l 0

92

27: Time::Time(int hr, int min, int sec) 28: { 29: SetTime(hr, min, sec); 30: } 31: 32: //Thit lp cc gi tr ca Hour, Minute, v Second 33: void Time::SetTime(int h, int m, int s) 34: { 35: Hour = (h >= 0 && h < 24) ? h : 0; 36: Minute = (m >= 0 && m < 60) ? m : 0; 37: Second = (s >= 0 && s < 60) ? s : 0; 38: } 39: 40: //Thit lp gi tr ca Hour 41: void Time::SetHour(int h) 42: { 43: Hour = (h >= 0 && h < 24) ? h : 0; 44: } 45: 46: //Thit lp gi tr ca Minute 47: void Time::SetMinute(int m) 48: { 49: Minute = (m >= 0 && m < 60) ? m : 0; 50: } 51: 52: //Thit lp gi tr ca Second 53: void Time::SetSecond(int s)

93

54: { 55: Second = (s >= 0 && s < 60) ? s : 0; 56: } 57: 58: //Ly gi tr ca Hour 59: int Time::GetHour() const 60: { 61: return Hour; 62: } 63: 64: //Ly gi tr ca Minute 65: int Time::GetMinute() const 66: { 67: return Minute; 68: } 69: 70: //Ly gi tr ca Second 71: int Time::GetSecond() const 72: { 73: return Second; 74: } 75: 76: //Hin th thi gian dng gi qun i: HH:MM:SS 77: void Time::PrintMilitary() const 78: { 79: cout << (Hour < 10 ? "0" : "") << Hour << ":" 80: << (Minute < 10 ? "0" : "") << Minute << ":"

94

81: 82: } 83:

<< (Second < 10 ? "0" : "") << Second;

84: //Hin th thi gian dng chun: HH:MM:SS AM (hay PM) 85: void Time::PrintStandard() const 86: { 87: cout << ((Hour == 12) ? 12 : Hour % 12) << ":" 88: 89: 90: 91: } 92: 93: int main() 94: { 95: const Time T(19, 33, 52); //i tng hng 96: 97: T.SetHour(12); //ERROR: non-const member function 98: T.SetMinute(20); //ERROR: non-const member function 99: T.SetSecond(39); //ERROR: non-const member function 100: return 0; 101: } << (Minute < 10 ? "0" : "") << Minute << ":" << (Second < 10 ? "0" : "") << Second << (Hour < 12 ? " AM" : " PM");

Chng trnh ny khai bo mt i tng hng ca lp Time v c gng sa i i tng vi cc hm thnh vin khng hng SetHour(), SetMinute() v SetSecond(). Cc li cnh bo c pht sinh bi trnh bin dch (Borland C++) nh hnh 3.13.

95

Hnh 3.13: Cc cnh bo ca chng trnh v d 3.13 Lu : Hm thnh vin const c th c a nng ha vi mt phin bn non-const. Vic la chn hm thnh vin a nng ha no s dng c to mt cch t ng bi trnh bin dch da vo ni m i tng c khai bo const hay khng.Mt i tng const khng th c thay i bi php gn v th n phi c khi ng. Khi mt thnh vin d liu ca mt lp c khai bo const, mt b khi to thnh vin (member initializer) phi c s dng cung cp cho constructor vi gi tr ban u ca thnh vin d liu i vi mt i tng ca lp. V d 3.14: Chng trnh sau s dng mt b khi to thnh vin khi to mt hng ca kiu d liu c sn.
CT3_14.CPP

1: #include <iostream.h> 2: 3: class IncrementClass 4: { 5: public: 6: IncrementClass (int C = 0, int I = 1); 7: void AddIncrement() 8: { 9: Count += Increment; 10: } 11: void Print() const; 12: private: 13: int Count; 14: const int Increment; //Thnh vin d liu const 15: }; 16:

96

17: //Constructor ca lp IncrementClass 18: //B khi to vi thnh vin const 19: IncrementClass::IncrementClass (int C, int I) : Increment(I) 20: { 21: Count = C; 22: } 23: 24: //In d liu 25: void IncrementClass::Print() const 26: { 27: cout << "Count = " << Count 28: # 30: } 31: 32: int main() 33: { 34: IncrementClass Value(10, 5); 35: 36: cout << "Before incrementing: "; 37: Value.Print(); 38: for (int J = 1; J <= 3; J++) 40: { 41: Value.AddIncrement(); 42: cout << "After increment " << J << ": "; 43: Value.Print(); 44: } 45: return 0; # << ", Increment = " << Increment << endl;

97

46: }

Chng trnh ny s dng c php b khi to thnh vin khi to thnh vin d liu const Increment ca lp IncrementClass dng 19. Chng ta chy v d 3.14, kt qu hnh 3.14

Hnh 3.14: Kt qu ca v d 3.14 K hiu : Increment(I) ( dng 19 ca v d 3.14) sinh ra Increment c khi ng vi gi tr l I. Nu nhiu b khi to thnh vin c cn, n gin bao gm chng trong danh sch phn cch du phy sau du hai chm. Tt c cc thnh vin d liu c th c khi to s dng c php b khi to thnh vin.Nu trong v d 3.14 chng ta c gng khi to Increment vi mt lnh gn hn l vi mt b khi to thnh vin nh sau: IncrementClass::IncrementClass (int C, int I) { Count = C; Increment = I; } Khi trnh bin dch (Borland C++) s c thng bo li nh sau:

Hnh 3.15: Thng bo li khi c gng khi to mt thnh vin d liu const bng php gn

3.14 LP NH L CC THNH VIN CA CC LP KHC


Mt lp c th c cc i tng ca cc lp khc nh cc thnh vin. Khi mt i tng i vo phm vi, constructor ca n c gi mt cch t ng, v th chng ta cn m t cc tham s c truyn nh th no ti cc constructor ca i tng thnh vin. Cc i tng thnh vin c xy dng theo th t m trong chng c khai bo (khng theo th t m chng c lit k trong danh sch b khi to thnh vin ca 98

constructor) v trc cc i tng ca lp cha ng chng c xy dng. V d 3.15: Chng trnh sau minh ha cc i tng nh cc thnh vin ca cc i tng khc.
CT3_15.CPP

1: #include <iostream.h> 2: #include <string.h> 3: 4: class Date 5: { 6: public: 7: Date(int = 1, int = 1, int = 1900); //Constructor mc nh 8: void Print() const; //In ngy theo dng Month/Day/Year 9: private: 10: int Month; //1-12 11: int Day; //1-31 12: int Year; //Nm bt k 13: //Hm tin ch kim tra Day tng thch i vi Month v Year 14: int CheckDay(int); 15: }; 16: 17: class Employee 18: { 19: public: 20: Employee(char *, char *, int, int, int, int, int, int); 21: void Print() const; 22: private: 23: char LastName[25]; 24: char FirstName[25];

99

25: Date BirthDate; 26: Date HireDate; 27: }; 28: 29: //Constructor: xc nhn gi tr tng thch ca Month 30: //Gi hm CheckDay() xc nhn gi tr tng thch ca Day 31: Date::Date(int Mn, int Dy, int Yr) 32: { 33: if (Mn > 0 && Mn <= 12) 34: Month = Mn; 35: else 36: { 37: Month = 1; 38: cout << "Month " << Mn << " invalid. Set to Month 1." 39: 40: } 41: Year = Yr; 42: Day = CheckDay(Dy); 43: cout << "Date object constructor for date "; 44: Print(); 45: cout << endl; 46: } 47: 48: //Hm tin ch xc nhn gi tr Day tng thch a vo Month v Year 49: int Date::CheckDay(int TestDay) 50: { << endl;

100

51: static int DaysPerMonth[13] = {0, 31, 28, 31, 30, 31, 52: 9; 9; 9; 9; 9; 9; # 53: 54: if (TestDay > 0 && TestDay <= DaysPerMonth[Month]) 55: return TestDay; 56: if (Month == 2 && TestDay == 29 && 57: ; ; (Year % 400 == 0 || (Year % 4 == 0 && Year % 100 != 0))) 58: return TestDay; 59: cout << "Day " << TestDay << "invalid. Set to Day 1." << endl; 60: return 1; 61: } 62: 63: //In i tng Date dng Month/Day/Year 64: void Date::Print() const 65: { 66: cout << Month << '/' << Day << '/' << Year; 67: } 68: 69: Employee::Employee(char *FName, char *LName, 70: 71: int BMonth, int BDay, int BYear, int HMonth, int HDay, int HYear) # # # 30, 31, 31, 30,31, 30, 31};

72: :BirthDate(BMonth, BDay, BYear), HireDate(HMonth, HDay, HYear) 73: { 74: //Sao chp FName vo FirstName v phi chc chn rng n ph hp 75: int Length = strlen(FName);

101

76: 77: Length = Length < 25 ? Length : 24; 78: strncpy(FirstName, FName, Length); 79: FirstName[Length] = '\0'; 80: //Sao chp LName vo LastName v phi chc chn rng n ph hp 81: Length = strlen(LName); 82: Length = Length < 25 ? Length : 24; 83: strncpy(LastName, LName, 24); 84: LastName[Length] = '\0'; 85: cout << "Employee object constructor: " 86: 87: } 88: 89: void Employee::Print() const 90: { 91: cout << LastName << ", " << FirstName << endl << "Hired: "; 92: HireDate.Print(); 93: cout << " Birthday: "; 94: BirthDate.Print(); 95: cout << endl; 96: } 97: 98: int main() 99: { 100: Employee E("Bob", "Jones", 7, 24, 49, 3, 12, 88); 101: << FirstName << ' ' << LastName << endl;

102

102 cout << endl; 103: E.Print(); 104: cout << endl << "Test Date constructor with invalid values:" 105: << endl;

106: Date D(14, 35, 94); //Cc gi tr Date khng hp l 107: return 0; 108: }

Chng trnh gm lp Employee cha cc thnh vin d liu private LastName, FirstName, BirthDate v HireDate. Cc thnh vin BirthDate v HireDate l cc i tng ca lp Date m cha cc thnh vin d liu private Month, Day v Year. Chng trnh khi to mt i tng Employee, v cc khi to v cc hin th cc thnh vin d liu ca n. Ch v c php ca phn u trong nh ngha constructor ca lp Employee:Employee::Employee(char *FName, char *LName, int BMonth, int BDay, int BYear, int HMonth, int HDay, int HYear) :BirthDate(BMonth, BDay, BYear), HireDate(HMonth, HDay, HYear) Constructor ly tm tham s (FName, LName, BMonth, BDay, BYear, HMonth, HDay, v HYear). Du hai chm trong phn u phn tch cc b khi to t danh sch cc tham s. Cc b khi to nh r cc tham s truyn chon constructor ca cc i tng thnh vin. V th BMonth, BDay v BYear c truyn cho constructor ca i tng BirthDate, v HMonth, HDay, v HYear c truyn cho constructor ca i tng HireDate. Nhiu b khi to c phn tch bi du phy. Chng ta chy v d 3.15, kt qu hnh 3.16

Hnh 3.16: Kt qu ca v d 3.15

103

Mt i tng thnh vin khng cn c khi to thng qua mt b khi to thnh vin. Nu mt b khi to thnh vin khng c cung cp, constructor mc nh ca i tng thnh vin s c gi mt cch t ng. Cc gi tr nu c thit lp bi constructor mc nh th c th c ghi bi cc hm set.

3.15 CC HM V CC LP FRIEND
Mt hm friend ca mt lp c nh ngha bn ngoi phm vi ca lp , lc ny c quyn truy cp n cc thnh vin private hoc protected ca mt lp. Mt hm hay ton b lp c th c khai bo l mt friend ca lp khc. khai bo mt hm l mt friend ca mt lp, ng trc prototype ca hm trong nh ngha lp vi t kha friend. nh sau: friend <function-declarator>; khai bo mt lp l friend ca lp khc nh sau: friend <class-name>; V d 3.16: Chng trnh sau minh ha khai bo v s dng hm friend.
CT3_16.CPP

1: #include <iostream.h> 2: 3: class Count 4: { 5: friend void SetX(Count &, int); //Khai bo friend 6: public: 7: Count()//Constructor 8: { 9: X = 0; 10: } 11: void Print() const //Xut 12: { 13: cout << X << endl; 14: } 15: private: 16: int X; 17: }; 18: 19: //C th thay i d liu private ca lp Count v

104

20: //SetX() khai bo l mt hm friend ca lp Count 21: void SetX(Count &C, int Val) 22: { 23: C.X = Val; //Hp l: SetX() l mt hm friend ca lp Count 24: } 25: 26: int main() 27: { 28: Count Object; 29: 30: cout << "Object.X after instantiation: "; 31: Object.Print(); 32: cout << "Object.X after call to SetX friend function: "; 33: SetX(Object, 8); //Thit lp X vi mt friend 34: Object.Print(); 35: return 0; 36: }

Chng ta chy v d 3.16, kt qu hnh 3.17

Hnh 3.17: Kt qu ca v d 3.16 C th ch nh cc hm c a nng ha l cc friend ca lp. Mi hm c a nng ha phi c khai bo tng minh trong nh ngha lp nh l mt friend ca lp.

3.16 CON TR THIS


Khi mt hm thnh vin tham chiu thnh vin khc ca lp cho i tng c th ca lp , lm th no C++ bo m rng i tng thch hp c tham chiu? Cu tr li l mi i tng duy tr mt con tr tr ti 105

chnh n gi l con tr this l mt tham s n trong tt c cc tham chiu ti cc thnh vin bn trong i tng . Con tr this cng c th c s dng tng minh. Mi i tng c th xc nh a ch ca chnh mnh bng cch s dng t kha this. Con tr this c s dng tham chiu c cc thnh vin d liu v hm thnh vin ca mt i tng. Kiu ca con tr this ph thuc vo kiu ca i tng v trong hm thnh vin con tr this c s dng l khai bo const. Chng hn, mt hm thnh vin khng hng ca lp Employee con tr this c kiu l: Employee * const //Con tr hng tr ti i tng Employee i vi mt hm thnh vin hng ca lp Employee con tr this c kiu l: const Employee * const //Con tr hng tr ti i tng Employee m l mt hng V d 3.17: Chng trnh sau minh ha s dng tng minh ca con tr this cho php mt hm thnh vin ca lp Test in d liu X ca mt i tng Test.
CT3_17.CPP

1: #include <iostream.h> 2: 3: class Test 4: { 5: public: 6: Test(int = 0); // Constructor mc nh 7: void Print() const; 8: private: 9: int X; 10: }; 11: 12: Test::Test(int A) 13: { 14: X = A; 15: } 16: 17: void Test::Print() const 18: { 19: cout << " X = " << X << endl 20: << " this->X = " << this->X << endl

106

21: 22: } 23:

<< "(*this).X = " << (*this).X << endl;

24: int main() 25: { 26: Test A(12); 27: 28: A.Print(); 29: return 0; 30: }

Chng ta chy v d 3.17, kt qu hnh 3.18

Hnh 3.18: Kt qu ca v d 3.17 Mt cch khc s dng con tr this l cho php mc vo nhau cc li gi hm thnh vin. V d 3.18: Chng trnh sau minh ha tr v mt tham chiu ti mt i tng Time cho php cc li gi hm thnh vin ca lp Time c mc ni vo nhau.
CT3_18.CPP

1: #include <iostream.h> 2: 3: class Time 4: { 5: public: 6: Time(int = 0, int = 0, int = 0); // Constructor mc nh 7: // Cc hm set

107

8: Time &SetTime(int, int, int); // Thit lp Hour, Minute va Second 9: Time &SetHour(int); // Thit lp Hour 10: Time &SetMinute(int); // Thit lp Minute 11: Time &SetSecond(int); // Thit lp Second 12: // Cc hm get 13: int GetHour() const; // Tr v Hour 14: int GetMinute() const; // Tr v Minute 15: int GetSecond() const; // Tr v Second 16: // Cc hm in 17: void PrintMilitary() const; // In thi gian theo dng gi qun i 18: void PrintStandard() const; // In thi gian theo dng gi chun 19: private: 20: int Hour; // 0 - 23 21: int Minute; // 0 - 59 22: int Second; // 0 - 59 23: }; 24: 25: // Constructor khi ng d liu private 26: // Gi hm thnh vin SetTime() thit lp cc bin 27: // Cc gi tr mc nh l 0 28: Time::Time(int Hr, int Min, int Sec) 29: { 30: SetTime(Hr, Min, Sec); 31: } 32:

108

33: // Thit lp cc gi tr ca Hour, Minute, v Second 34: Time &Time::SetTime(int H, int M, int S) 35: { 36: Hour = (H >= 0 && H < 24) ? H : 0; 37: Minute = (M >= 0 && M < 60) ? M : 0; 38: Second = (S >= 0 && S < 60) ? S : 0; 39: return *this; // Cho php mc ni 40: } 41: 42: // Thit lp gi tr ca Hour 43: Time &Time::SetHour(int H) 44: { 45: Hour = (H >= 0 && H < 24) ? H : 0; 46: return *this; // Cho php mc ni 47: } 48: 49: // Thit lp gi tr ca Minute 50: Time &Time::SetMinute(int M) 51: { 52: Minute = (M >= 0 && M < 60) ? M : 0; 53: return *this; // Cho php mc ni 54: } 55: 56: // Thit lp gi tr ca Second 57: Time &Time::SetSecond(int S) 58: { 59: Second = (S >= 0 && S < 60) ? S : 0;

109

60: return *this; // Cho php mc ni 61: } 62: 63: // Ly gi tr ca Hour 64: int Time::GetHour() const 65: { 66: return Hour; 67: } 68: 69: // Ly gi tr ca Minute 70: int Time::GetMinute() const 71: { 72: return Minute; 73: } 74: 75: // Ly gi tr ca Second 76: int Time::GetSecond() const 77: { 78: return Second; 79: } 80: 81: // Hin th thi gian dng gi qun i: HH:MM:SS 82: void Time::PrintMilitary() const 83: { 84: cout << (Hour < 10 ? "0" : "") << Hour << ":" 85: 86: << (Minute < 10 ? "0" : "") << Minute << ":" << (Second < 10 ? "0" : "") << Second;

110

87: } 88: 89: // Hin th thi gian dng chun: HH:MM:SS AM (hay PM) 90: void Time::PrintStandard() const 91: { 92: cout << ((Hour == 0 || Hour == 12) ? 12 : Hour % 12) << ":" 93: 94: 95: 96: } 97: 100: int main() 101: { 102: Time T; 103: 104: // Cc li gi mc ni vo nhau 105: T.SetHour(18).SetMinute(30).SetSecond(22); 106: cout << "Military time: "; 107: T.PrintMilitary(); 108: cout << endl << "Standard time: "; 109: T.PrintStandard(); 110: cout << endl << endl << "New standard time: "; 111: // Cc li gi mc ni vo nhau 112: T.SetTime(20, 20, 20).PrintStandard(); 113: cout << endl; 114: return 0; 115: } << (Minute < 10 ? "0" : "") << Minute << ":" << (Second < 10 ? "0" : "") << Second << (Hour < 12 ? " AM" : " PM");

111

Cc hm thnh vin SetTime(), SetHour(), SetMinute() v SetSecond() mi hm u tr v *this vi kiu tr v l Time &. Ton t chm lin kt t tri sang phi, v vy biu thc: T.SetHour(18).SetMinute(30).SetSecond(22); u tin gi T.SetHour(18) th tr v mt tham chiu ti i tng T l gi tr ca li gi hm ny. Phn cn li ca biu thc c hiu nh sau: T.SetMinute(30).SetSecond(22); T.SetMinute(30) gi thc hin v tr v tng ng ca T. Phn cn ca biu thc l: T.SetSecond(22); Chng ta chy v d 3.18, kt qu hnh 3.19

Hnh 3.19: Kt qu ca v d 3.18

3.17 CC I TNG C CP PHT NG


Cc i tng c th c cp pht ng ging nh cc d liu khc bng ton t new v delete. Chng hn: Time *TimePtr = new Time(1,20,26); .. delete TimePtr; Ton t new t ng gi hm constructor ,v ton t delete t ng gi destructor.

3.18 CC THNH VIN TNH CA LP


Bnh thng, mi i tng ca mt lp c bn sao chp ca chnh n ca tt c cc thnh vin d liu ca lp. Trong cc trng hp nht nh ch c duy nht mt bn chp thnh vin d liu c bit cn phi dng chung bi tt c cc i tng ca mt lp. Mt thnh vin d liu tnh c s dng cho nhng iu v cc l do khc. Mt thnh vin d liu tnh biu din thng tin ton lp (class-wide). Khai bo mt thnh vin tnh bt u vi t kha static. Mc d cc thnh vin d liu tnh c th ging nh cc bin ton cc, cc thnh vin d liu tnh c phm vi lp. Cc thnh vin tnh c th l public, private hoc protected. Cc thnh vin d liu tnh phi c khi 112

to mt ln (v ch mt ln) ti phm vi file. Cc thnh vin lp tnh public c th c truy cp thng qua bt k i tng no ca lp , hoc chng c th c truy cp thng qua tn lp s dng ton t nh phm vi. Cc thnh vin lp tnh private v protected phi c truy cp thng qua cc hm thnh vin public ca lp hoc thng qua cc friend ca lp. Cc thnh vin lp tnh tn ti ngay c khi i tng ca lp khng tn ti. truy cp mt thnh vin lp tnh public khi cc i tng ca lp khng tn ti, n gin thm vo u tn lp v ton t nh phm vi cho thnh vin d liu. truy cp mt thnh vin lp tnh private hoc protected khi cc i tng ca lp khng tn ti, mt hm thnh vin public phi c cung cp v hm phi c gi bi thm vo u tn ca n vi tn lp v ton t nh phm vi. V d 3.19: Chng trnh sau minh ha vic s dng thnh vin d liu tnh private v mt hm thnh vin tnh public.
CT3_19.CPP

1: #include <iostream.h> 2: #include <string.h> 3: #include <assert.h> 4: 5: class Employee 6: { 7: public: 8: Employee(const char*, const char*); // Constructor 9: ~Employee(); // Destructor 10: char *GetFirstName() const; // Tr v first name 11: char *GetLastName() const; // Tr v last name 12: // Hm thnh vin tnh 13: static int GetCount(); // Tr v s i tng khi to 14: private: 15: char *FirstName; 16: char *LastName; 17: // static data member 18: static int Count; // S i tng khi to 19: }; 20:

113

21: // Khi to thnh vin d liu tnh 22: int Employee::Count = 0; 23: 24: // nh ngha hm thnh vin tnh m tr v s i tng khi to 25: int Employee::GetCount() 26: { 27: return Count; 28: } 29: 30: // Constructor cp pht ng cho first name v last name 31: Employee::Employee(const char *First, const char *Last) 32: { 33: FirstName = new char[ strlen(First) + 1 ]; 34: assert(FirstName != 0); // Bo m vng nh c cp pht 35: strcpy(FirstName, First); 36: LastName = new char[ strlen(Last) + 1 ]; 37: assert(LastName != 0); // Bo m vng nh c cp pht 38: strcpy(LastName, Last); 39: ++Count; // Tng s i tng ln 1 40: cout << "Employee constructor for " << FirstName 41: 42: } 43: 44: // Destructor gii phng vng nh cp pht 45: Employee::~Employee() 46: { << ' ' << LastName << " called." << endl;

114

47: cout << "~Employee() called for " << FirstName 48: << ' ' << LastName << endl;

49: delete FirstName; 50: delete LastName; 51: --Count; // Gim s i tng xung 1 52: } 53: 54: // Tr v first name 55: char *Employee::GetFirstName() const 56: { 57: char *TempPtr = new char[strlen(FirstName) + 1]; 58: assert(TempPtr != 0); // Bo m vng nh c cp pht 59: strcpy(TempPtr, FirstName); 60: return TempPtr; 61: } 62: 63: // Tr v last name 64: char *Employee::GetLastName() const 65: { 66: char *TempPtr = new char[strlen(LastName) + 1]; 67: assert(TempPtr != 0); // Bo m vng nh c cp pht 68: strcpy(TempPtr, LastName); 69: return TempPtr; 70: } 71: 72: int main() 73: {

115

74: cout << "Number of employees before instantiation is " 75: << Employee::GetCount() << endl; // S dng tn lp

76: Employee *E1Ptr = new Employee("Susan", "Baker"); 77: Employee *E2Ptr = new Employee("Robert", "Jones"); 78: cout << "Number of employees after instantiation is " 79: << E1Ptr->GetCount() << endl;

80: cout << endl << "Employee 1: " 81: 82: 83: 84: 85: << E1Ptr->GetFirstName() << " " << E1Ptr->GetLastName() << endl << "Employee 2: " << E2Ptr->GetFirstName() << " " << E2Ptr->GetLastName() << endl << endl;

86: delete E1Ptr; 87: delete E2Ptr; 88: cout << "Number of employees after deletion is " 89: 90: 91: } << Employee::GetCount() << endl; return 0;

Thnh vin d liu Count c khi to l zero phm vi file vi lnh: int Employee::Count = 0; Thnh vin d liu Count duy tr s cc i tng ca lp Employee c khi to. Khi i tng ca lp Employee tn ti, thnh vin Count c th c tham chiu thng qua bt k hm thnh vin no ca mt i tng Employee trong v d ny, Count c tham chiu bi c constructor ln destructor. Khi cc i tng ca lp Employee khng tn ti, thnh vin Count c th vn c tham chiu nhng ch thng qua mt li gi hm thnh vin tnh public GetCount() nh sau: Employee::GetCount()

116

Hm GetCount() c s dng xc nh s cc i tng ca Employee khi to hin hnh. Ch rng khi khng c cc i tng trong chng trnh, li gi hm Employee::GetCount() c a ra. Tuy nhin khi c cc i tng khi ng hm GetCount() c th c gi thng qua mt trong cc i tng nh sau: E1Ptr->GetCount() Trong chng trnh cc dng 34, 37, 58 v 67 s dng hm assert() (nh ngha trong assert.h). Hm ny kim tra gi tr ca biu thc. Nu gi tr ca biu thc l 0 (false), hm assert() in mt thng bo li v gi hm abort() (nh ngha trong stdlib.h) kt thc chng trnh thc thi. Nu biu thc c gi tr khc 0 (true) th chng trnh tip tc. iu ny rt c ch cho cng c debug i vi vic kim tra nu mt bin c gi tr ng. Chng hn hm dng 34 hm assert() kim tra con tr FirstName xc nh nu n khng bng 0 (null). Nu iu kin trong khng nh (assertion) cho trc l ng, chng trnh tip tc m khng ngt. Nu iu kin trong khng nh cho trc l sai, mt thng bo li cha s dng, iu kin c kim tra, v tn file trong s khng nh xut hin c in, v chng trnh kt thc. Khi lp trnh vin c th tp trung vo vng ny ca on m tm li. Cc khng nh khng phi xa t chng trnh khi debug xong. Khi cc khng nh khng cn cn thit cho mc ch debug trong mt chng trnh, dng sau: #define NDEBUG c thm vo u file chng trnh. iu ny pht sinh tin x l b qua tt c cc khng nh thay th cho lp trnh vin xa mi khng nh bng tay. Chng ta chy v d 3.19, kt qu hnh 3.20

Hnh 3.20: Kt qu ca v d 3.19 Mt hm thnh vin c th c khai bo l static nu n khng truy cp n cc thnh vin khng tnh. Khng ging nh cc thnh vin khng tnh, mt hm thnh vin tnh khng c con tr this bi v cc thnh vin d liu tnh v cc hm thnh vin tnh tn ti c lp vi bt k i tng no ca lp. Ch : Hm thnh vin d liu tnh khng c l const.

4.1 DN NHP
117

Trong chng 3, chng ta tm hiu cc iu c bn ca cc lp C++ v khi nim kiu d liu tru tng (ADTs). Cc thao tc trn cc i tng ca lp (ngha l cc thc th ca ADTs) c thc hin bi gi cc thng ip (di dng cc li gi hm thnh vin) ti cc i tng. K php gi hm ny th cng knh cho cc loi lp nht nh, c bit l cc lp ton hc. i vi cc loi lp ny s l p s dng tp cc ton t c sn phong ph ca C++ ch r cc thao tc ca i tng. Trong chng ny tm hiu lm th no cho php cc ton t ca C++ lm vic vi cc i tng ca lp. X l ny c gi l a nng ha ton t (operator overloading). Ton t << c s dng nhiu mc ch trong C++ l ton t chn dng (stream-insertion) v ton t dch chuyn tri. y l mt v d ca a nng ha ton t. Tng t >> cng c a nng ha. N c s dng va ton t trch dng (stream-extraction) v ton t dch chuyn phi. C++ cho php cc lp trnh vin a nng ha hu ht cc ton t biu th ng cnh m trong chng c s dng. Trnh bin dch pht sinh on m thch hp da trn kiu m trong ton t c s dng. Mt vi ton t c a nng ha thng xuyn, c bit l ton t gn v cc ton t s hc nh + v -. Cng vic thc hin bi a nng ha cc ton t cng c th c thc hin bi cc li gi hm tng minh, nhng k php thng s dng d dng c.

4.2 CC NGUYN TC C BN CA A NNG HA TON T


Lp trnh vin c th s dng cc kiu c sn v c th nh ngha cc kiu mi. Cc kiu c th c s dng vi tp cc ton t phong ph. Cc ton t cung cp cho cc lp trnh vin vi k php ngn ngn cho vic biu th cc thao tc ca i tng ca cc kiu c sn. Cc lp trnh vin c th s dng cc ton t vi cc kiu do ngi dng nh ngha. Mc d C++ khng cho php cc ton t mi c to, n cho php cc ton t tn ti c a nng ha sao cho khi cc ton t ny c s dng vi cc i tng ca lp, cc ton t c ngha thch hp cc kiu mi. y chnh l mt c im mnh ca C++. Cc ton t c a nng ha bng cch vit mt nh ngha hm (bao gm phn u v thn) nh khi chng ta vit mt hm bnh thng, ngoi tr tn hm by gi tr thnh t kha operator theo sau bi k hiu ca ton t c a nng ha. Prototype ca n c dng nh sau: type operator operator_symbol ( parameter_list ); s dng mt ton t mt cc i tng ca lp, ton t phi c a nng ha ngoi tr hai iu. iu th nht ton t gn c th s dng vi mi lp m khng cn a nng ha. Cch c x mc nh ca ton t gn l mt php gn thnh vin ca cc thnh vin d liu ca lp. Chng ta nhn thy rng sao chp thnh vin mc nh th nguy him i vi cc lp vi cc thnh vin m c cp pht ng. Chng ta s a nng ha mt cch tng minh ton t gn i vi cc lp nh th. iu th hai ton t a ch (&) cng c th c s dng vi cc i tng ca bt k lp no m khng cn a nng ha; N tr v a ch ca i tng trong b nh. Ton t a ch cng c th c a nng ha.

4.3 CC GII HN CA A NNG HA TON T


Phn ln cc ton t ca C++ c th c a nng ha. Hnh 4.1 cho thy cc ton t c th c a nng ha v hnh 4.1 l cc ton t khng th a nng ha. + * / % 118 ^ & |

~ /= <<= --

! %= == ->*

= ^= != ,

< &= <= ->

> |= >= []

+= << && ()

-= >> || new

*= >>= ++ delete

Hnh 4.1: Cc ton t c th c a nng ha . .* :: ?: sizeof

Hnh 4.2: Cc ton t khng th a nng ha Ch rng ton t ngoc trn () trong bng 4.1 l ton t gi hm. V ton t ny ng sau tn hm c th cha trong n nhiu tham s do ton t ngoc trn l mt ton t nhiu ngi. Th t u tin ca mt ton t khng th c thay i bi a nng ha. iu ny c th dn ti cc tnh trng bt tin trong mt ton t c a nng ha theo mt cch i vi mc u tin c nh ca n th khng thch hp. Tuy nhin, cc du ngoc n c th c s dng t th t c lng ca cc ton t a nng ha trong mt biu thc. Tnh kt hp ca mt ton t khng th c thay i bi a nng ha. Cc tham s mc nh khng th s dng vi mt ton t a nng ha. Khng th thay i s cc ton hng m mt ton t yu cu: a nng ha cc ton t mt ngi vn l cc ton t mt ngi; a nng ha cc ton t hai ngi vn l cc ton t hai ngi. Ton t ba ngi duy nht (?:) ca C++ khng th a nng ha. Cc ton t &, *, + v mi ton t c cc phin bn mt v hai ngi.; Cc phin bn mt v hai ngi ny c th c a nng ha ring bit. ngha ca lm sao mt ton t lm vic trn cc i tng ca cc kiu c sn khng th thay i bi vic a nng ha ton t. Chng hn, lp trnh vin khng th thay i ngha ca lm sao ton t (+) cng hai s nguyn. Vic a nng ha ton t ch lm vic vi cc i tng ca cc kiu do ngi dng nh ngha hoc vi mt s pha trn ca mt i tng ca kiu do ngi dng nh ngha v mt i tng ca mt kiu c sn. a nng ha mt ton t gn v mt ton t cng cho php cc lnh nh l: object2 = object2 + object1 khng bao hm ton t += cng c a nng ha php cc lnh nh l: object2 += object1 Hnh vi nh th c th c thc hin bi vic a nng ha r rng ton t += cho lp .

4.4 CC HM TON T C TH L CC THNH VIN CA LP HOC KHNG L CC THNH VIN


119

Cc hm ton t c th l cc hm thnh vin hoc hm khng thnh vin; hm khng thnh vin thng l cc hm friend. Cc hm thnh vin s dng ngm con tr this cha mt trong cc tham s i tng lp ca chng. Tham s lp phi c lit k mt cch tng minh trong li gi hm khng thnh vin. Khi a nng ha (), [], -> hoc =, hm a nng ha ton t phi c khai bo nh mt thnh vin lp. i vi cc ton t khc, cc hm a nng ha ton t c th l cc hm khng thnh vin (thng l cc hm friend). Liu c phi mt hm ton t c ci t nh mt hm thnh vin hoc nh hm khng thnh vin, ton t vn cn c s dng cng cch trong biu thc. Nh vy cch l cch ci t no tt nht? Khi mt hm ton t c ci t nh mt hm thnh vin, ton hng cc tri phi l mt i tng lp ca ton t. Nu ton hng bn tri phi l mt i tng ca lp khc hoc mt kiu c sn th hm ton t ny phi c ci t nh hm khng thnh vin. Mt hm ton t ci t nh hm khng thnh vin cn l mt friend nu hm phi truy cp n cc thnh vin private hoc protected. Cc hm thnh vin ch c gi khi ton hng tri ca mt ton t hai ngi l mt i tng c th ca lp , hoc khi ton hng n ca mt ton t mt ngi l mt i tng ca lp . V d 4.1: Chng ta xy dng lp s phc vi tn lp l Complex v a nng ha ton t + trn lp ny.
CT4_1.CPP

1: #include <iostream.h> 2: 3: class Complex 4: { 5: private: 6: double Real, Imaginary; 7: public: 8: Complex(double R=0.0,double I=0.0);// Constructor mc nh 9: void Print(); // Hin th s phc 10: Complex operator+(Complex Z); // Php cng gia hai s phc 11: Complex operator+(double R); // Php cng mt s phc vi mt s thc 12: }; 13: 14: Complex::Complex(double R,double I) 15: {

120

16: Real = R; 17: Imaginary = I; 18: } 19: 20: void Complex::Print() 21: { 22: cout<<'('<<Real<<','<<Imaginary<<')'; 23: } 24: 25: Complex Complex::operator + (Complex Z) 26: { 27: Complex Tmp; 28: Tmp.Real = Real + Z.Real; 29: Tmp.Imaginary = Imaginary + Z.Imaginary; 30: return Tmp; 31: } 32: 33: Complex Complex::operator + (double R) 34: { 35: Complex Tmp; 36: Tmp.Real = Real + R; 37: Tmp.Imaginary = Imaginary; 38: return Tmp; 39: } 40: 41: int main() 42: {

121

43: Complex X,Y(4.3,8.2),Z(3.3,1.1); 44: cout<<"X: "; 45: X.Print(); 46: cout<<endl<<"Y: "; 47: Y.Print(); 48: cout<<endl<<"Z: "; 49: Z.Print(); 50: X = Y + Z; 51: cout<<endl<<endl<<"X = Y + Z:"<<endl; 52: X.Print(); 53: cout<<" = "; 54: Y.Print(); 55: cout<<" + "; 56: Z.Print(); 57: X = Y + 3.5; 58: cout<<endl<<endl<<"X = Y + 3.5:"<<endl; 59: X.Print(); 60: cout<<" = "; 61: Y.Print(); 62: cout<<" + 3.5"; 63: return 0; 64: }

Hm thnh vin ton t operator + () (t dng 25 n 31 v t dng 33 n 39) tr v mt i tng c kiu Complex l tng ca hai s phc hoc tng ca mt s phc vi mt s thc. Ch rng i tng tam thi Tmp c dng bn trong hm operator + () gi kt qu, v l i tng c tr v. Chng ta chy v d 4.1, kt qu hnh 4.3 122

Hnh 4.3: Kt qu ca v d 4.1 Do a nng ha ton t + trn lp Complex v d 4.1, chng ta c th vit: X = Y + Z; Cu lnh ny c trnh bin dch hiu: X = Y.operator + (Z); Nh vy, trong biu thc Y + Z i tng bn tri ton t + (l i tng Y) l i tng m qua , hm thnh vin ton t operator + () c gi. Do hm thnh vin ton t + ch nhn mt tham s l i tng bn phi ton t v i tng bn tri ton t l i tng to li gi cho hm ton t v c truyn bi con tr this. Hm operator + () tr v mt i tng Complex. Do vy chng ta c th vit: (Y + Z).Print(); in trn mn hnh s phc ca i tng c tr v. i tng do Y + Z sinh ra nh vy l mt i tng tm thi. N s khng tn ti khi hm thnh Print() kt thc. Hn na khi tr v mt i tng, ton t + cho php mt chui php cng. Nn chng ta cng c th vit: X = X + Y + Z; Tuy nhin chng ta khng th no vit c cu lnh sau: X = 3.5 + Y; // Li !!! Chnh v l do ny chng ta chn mt hm khng thnh vin a nng ha mt ton t cho php ton t c giao hon. Ch rng hm khng thnh vin khng cn thit phi l hm friend nu cc hm set v get thch hp tn ti trong phn giao din public, v t bit nht nu cc hm set v get l cc hm inline. a nng ha ton t << phi c mt ton hng tri ca kiu ostream & (nh l cout trong biu thc cout<<X), v th n phi l hm khng thnh vin. Tng t, a nng ha ton t >> phi c mt ton hng tri ca kiu istream & (nh l cin trong biu thc cin>>X), v th v th n cng phi l hm khng thnh vin. 123

Ngoi tr a nng ha ton t >> v << lin quan n dng nhp/xut d liu chng ta c hnh 4.4 v cch a nng ha ton t nh sau: Biu thc a#b #a a=b a[b] a(b) a-> a++ a-Hm thnh vin a.operator#(b) a.operator() a.operator=(b) a.operator[](b) a.operator()(b) a.operator->() a.operator++(0) a.operator--(0) operator++(a,0) operator--(a,0) Hm khng thnh vin operator#(a,b) operator#(a)

Hnh 4.4: Vic ci t cc hm ton t

4.5 A NNG HO CC TON T HAI NGI


Cc ton t hai ngi c a nng ha trong hnh 4.5 sau: Ton t + * / % ^ & | = < V d a+b a-b a*b a/b a%b a^b a&b a|b a=b a<b Ton t += -= *= /= %= ^= &= |= << >> 124 V d a+=b a-=b a*=b a/=b a%=b a^=b a&=b a|=b a<<b a>>b Ton t <<= == != <= >= && || , [] ->* V d a<<=b a==b a!=b a<=b a>=b a&&b a||b a,b a[b] a->*b

>

a>b

>>=

a>>=b

Hnh 4.5: Cc ton t hai ngi c a nng ha Mt ton t hai ngi c th c a nng ha nh l hm thnh vin khng tnh vi mt tham s hoc nh mt hm khng thnh vin vi hai tham s (mt trong cc tham s ny phi l hoc l mt i tng lp hoc l mt tham chiu n i tng lp). V d 4.2: Chng ta xy dng lp s phc vi tn lp l Complex v a nng ha cc ton t tnh ton + - += -= v cc ton t so snh == != > >= < <= vi cc hm ton t l cc hm thnh vin.
CT4_2.CPP

1: #include <iostream.h> 2: #include <math.h> 3: 4: class Complex 5: { 6: private: 7: double Real, Imaginary; 8: public: 9: Complex(); // Constructor mc nh 10: Complex(double R,double I); 11: Complex (const Complex & Z); // Constructor sao chp 12: Complex (double R); // Constructor chuyn i 13: void Print(); // Hin th s phc 14: // Cc ton t tnh ton 15: Complex operator + (Complex Z); 16: Complex operator - (Complex Z); 17: Complex operator += (Complex Z); 18: Complex operator -= (Complex Z); 19: // Cc ton t so snh 20: int operator == (Complex Z);

125

21: int operator != (Complex Z); 22: int operator > (Complex Z); 23: int operator >= (Complex Z); 24: int operator < (Complex Z); 25: int operator <= (Complex Z); 26: private: 27: double Abs(); // Gi tr tuyt i ca s phc 28: }; 29: 30: Complex::Complex() 31: { 32: Real = 0.0; 33: Imaginary = 0.0; 34: } 35: 36: Complex::Complex(double R,double I) 37: { 38: Real = R; 39: Imaginary = I; 40: } 41: 42: Complex::Complex(const Complex & Z) 43: { 44: Real = Z.Real; 45: Imaginary = Z.Imaginary; 46: } 47:

126

48: Complex::Complex(double R) 49: { 50: Real = R; 51: Imaginary = 0.0; 52: } 53: 54: void Complex::Print() 55: { 56: cout<<'('<<Real<<','<<Imaginary<<')'; 57: } 58: 59: Complex Complex::operator + (Complex Z) 60: { 61: Complex Tmp; 62 63: Tmp.Real = Real + Z.Real; 64: Tmp.Imaginary = Imaginary + Z.Imaginary; 65: return Tmp; 66: } 67: 68: Complex Complex::operator - (Complex Z) 69: { 70: Complex Tmp; 71: 72: Tmp.Real = Real - Z.Real; 73: Tmp.Imaginary = Imaginary - Z.Imaginary; 74: return Tmp;

127

75: } 76: 77: Complex Complex::operator += (Complex Z) 78: { 79: Real += Z.Real; 80: Imaginary += Z.Imaginary; 81: return *this; 82: } 83: 84: Complex Complex::operator -= (Complex Z) 85: { 86: Real -= Z.Real; 87: Imaginary -= Z.Imaginary; 88: return *this; 89: } 90: 91: int Complex::operator == (Complex Z) 92: { 93: return (Real == Z.Real) && (Imaginary == Z.Imaginary); 94: } 95: 96: int Complex::operator != (Complex Z) 97: { 98: return (Real != Z.Real) || (Imaginary != Z.Imaginary); 99: } 100: 101: int Complex::operator > (Complex Z)

128

102: { 103: return Abs() > Z.Abs(); 104: } 105: 106: int Complex::operator >= (Complex Z) 107: { 108: return Abs() >= Z.Abs(); 109: } 110: 111: int Complex::operator < (Complex Z) 112: { 113: return Abs() < Z.Abs(); 114: } 115: 116: int Complex::operator <= (Complex Z) 117: { 118: return Abs() <= Z.Abs(); 119: } 120: 121: double Complex::Abs() 122: { 123: return sqrt(Real*Real+Imaginary*Imaginary); 124: } 125: 126: int main() 127: { 128: Complex X, Y(4.3,8.2), Z(3.3,1.1), T;

129

129 130: cout<<"X: "; 131: X.Print(); 132: cout<<endl<<"Y: "; 133: Y.Print(); 134: cout<<endl<<"Z: "; 135: Z.Print(); 136: cout<<endl<<"T: "; 137: T.Print(); 138: T=5.3;// Gi constructor chuyn kiu 139: cout<<endl<<endl<<"T = 5.3"<<endl; 140: cout<<"T: "; 141: T.Print(); 142: X = Y + Z; 143: cout<<endl<<endl<<"X = Y + Z: "; 144: X.Print(); 145: cout<<" = "; 146: Y.Print(); 147: cout<<" + "; 148: Z.Print(); 149: X = Y - Z; 150: cout<<endl<<"X = Y - Z: "; 151: X.Print(); 152: cout<<" = "; 153: Y.Print(); 154: cout<<" - "; 155: Z.Print();

130

156: cout<<endl<<endl<<"Y += T i.e "; 157: Y.Print(); 158: cout<<" += "; 159: T.Print(); 160: Y += T; 161: cout<<endl<<"Y: "; 162: Y.Print(); 163: cout<<endl<<"Z -= T i.e "; 164: Z.Print(); 165: cout<<" -= "; 166: T.Print(); 167: Z -= T; 168: cout<<endl<<"Z: "; 169: Z.Print(); 170: Complex U(X);// Gi constructor sao chp 171: cout<<endl<<endl<<"U: "; 172: U.Print(); 173: cout<<endl<<endl<<"Evaluating: X==U"<<endl; 174: if (X==U) 175: cout<<"They are equal"<<endl; 176: cout<<"Evaluating: Y!=Z"<<endl; 177: if (Y!=Z) 178: cout<<"They are not equal => "; 179: if (Y>Z) 180: cout<<"Y>Z"; 181: else 182: cout<<"Y<Z";

131

183: return 0; 184: }

Chng ta chy v d 4.2, kt qu hnh 4.6

Hnh 4.6: Kt qu ca v d 4.2 Dng th 11 ca chng trnh v d 4.2: Complex(const Complex &Z); l mt constructor sao chp (copy constructor). N khi ng mt i tng lp bng cch to mt sao chp ca mt i tng lp . Constructor sao chp thc hin cng vic ging nh ton t sao chp nhng n c mt vai tr c bit. Constructor sao chp ch nhn tham s l mt tham chiu ch n i tng thuc chnh lp m n c nh ngha. Cc constructor sao chp c dng mi khi mt s sao chp ca mt i tng cn thit nh khi c s truyn tham s bng tr, khi tr v mt i tng t hm, hoc khi khi ng mt i tng m c sao chp t i tng khc ca cng lp. Chng hn: Complex A(3.5, 4.5); 132

Complex B(A); // Gi constructor sao chp Complex C = B; // Gi constructor sao chp Complex MyFunc(Complex Z) // Gi constructor sao chp
{ return }

Z; // Gi constructor sao chp

Chng ta ch rng, du = trong cu lnh trn ng vi constructor sao chp ch khng phi l ton t gn . Nu chng ta khng nh ngha constructor sao chp, trnh bin dch to ra mt constructor sao chp mc nh s sao chp tng thnh vin mt. dng 12 ca chng trnh v d 4.2: Complex(double R); l mt constructor chuyn i (conversion constructor). Constructor ny ly mt tham s double v khi to i tng Complex m phn thc bng gi tr tham s truyn vo v phn o bng 0.0 (t dng 48 n 52). Bt k mt constructor no c tham s n c th c ngh nh mt constructor chuyn i. Constructor chuyn i s i mt s thc thnh mt i tng Complex ri gn cho i tng ch Complex. Chng hn: T = 3.5; // Ngm nh: T = Complex(3.5) Trnh bin dch t ng dng constructor chuyn i to mt i tng tm thi Complex, ri dng ton t gn gn i tng tm thi ny cho i tng khc ca Complex. Chng hn cu lnh sau vn ng: X = Y + 3.5; // Ngm nh: X = Y + Complex(3.5); Nh vy mt constructor chuyn i c s dng thc hin mt s chuyn i ngm nh. V d 4.3: Ly li v d 4.2 nhng cc hm ton t +, - v cc hm ton t so snh l hm khng thnh vin.
CT4_3.CPP

1: #include <iostream.h> 2: #include <math.h> 3: 4: class Complex 5: { 6: private:

133

7: double Real,Imaginary; 8: public: 9: Complex(); // Constructor mc nh 10: Complex(double R,double I); 11: Complex (const Complex & Z); // Constructor sao chp 12: Complex (double R); // Constructor chuyn i 13: void Print(); // Hin th s phc 14: // Cc ton t tnh ton 15: friend Complex operator + (Complex Z1,Complex Z2); 16: friend Complex operator - (Complex Z1,Complex Z2); 17: Complex operator += (Complex Z); 18: Complex operator -= (Complex Z); 19: // Cc ton t so snh 20: friend int operator == (Complex Z1,Complex Z2); 21: friend int operator != (Complex Z1,Complex Z2); 22: friend int operator > (Complex Z1,Complex Z2); 23: friend int operator >= (Complex Z1,Complex Z2); 24: friend int operator < (Complex Z1,Complex Z2); 25: friend int operator <= (Complex Z1,Complex Z2); 26: private: 27: double Abs(); // Gi tr tuyt i ca s phc 28: }; 29: 30: Complex::Complex() 31: { 32: Real = 0.0; 33: Imaginary = 0.0;

134

34: } 35: 36: Complex::Complex(double R,double I) 37: { 38: Real = R; 39: Imaginary = I; 40: } 41: 42: Complex::Complex(const Complex & Z) 43: { 44: Real = Z.Real; 45: Imaginary = Z.Imaginary; 46: } 47: 48: Complex::Complex(double R) 49: { 50: Real = R; 51: Imaginary = 0.0; 52: } 53: 54: void Complex::Print() 55: { 56: cout<<'('<<Real<<','<<Imaginary<<')'; 57: } 58: 59: Complex operator + (Complex Z1,Complex Z2) 60: {

135

61: Complex Tmp; 62: 63: Tmp.Real = Z1.Real + Z2.Real; 64: Tmp.Imaginary = Z1.Imaginary + Z2.Imaginary; 65: return Tmp; 66: } 67: 68: Complex operator - (Complex Z1,Complex Z2) 69: { 70: Complex Tmp; 71: 72: Tmp.Real = Z1.Real - Z2.Real; 73: Tmp.Imaginary = Z1.Imaginary - Z2.Imaginary; 74: return Tmp; 75: } 76: 77: Complex Complex::operator += (Complex Z) 78: { 79: Real += Z.Real; 80: Imaginary += Z.Imaginary; 81: return *this; 82: } 83: 84: Complex Complex::operator -= (Complex Z) 85: { 86: Real -= Z.Real; 87: Imaginary -= Z.Imaginary;

136

88: return *this; 89: } 90: 91: int operator == (Complex Z1,Complex Z2) 92: { 93: return (Z1.Real == Z2.Real) && (Z1.Imaginary == Z2.Imaginary); 94: } 95: 96: int operator != (Complex Z1,Complex Z2) 97: { 98: return (Z1.Real != Z2.Real) || (Z1.Imaginary != Z2.Imaginary); 99: } 100: 101: int operator > (Complex Z1,Complex Z2) 102: { 103: return Z1.Abs() > Z2.Abs(); 104: } 105: 106: int operator >= (Complex Z1,Complex Z2) 107: { 108: return Z1.Abs() >= Z2.Abs(); 109: } 110: 111: int operator < (Complex Z1,Complex Z2) 112: { 113: return Z1.Abs() < Z2.Abs();

137

114: } 115: 116: int operator <= (Complex Z1,Complex Z2) 117: { 118: return Z1.Abs() <= Z2.Abs(); 119: } 120: 121: double Complex::Abs() 122: { 123: return sqrt(Real*Real+Imaginary*Imaginary); 124: } 125: 126: int main() 127: { 128: Complex X,Y(4.3,8.2),Z(3.3,1.1); 129: 130: cout<<"X: "; 131: X.Print(); 132: cout<<endl<<"Y: "; 133: Y.Print(); 134: cout<<endl<<"Z: "; 135: Z.Print(); 136: X = Y + 3.6; 137: cout<<endl<<endl<<"X = Y + 3.6: "; 138: X.Print(); 139: cout<<" = "; 140: Y.Print();

138

141: cout<<" + 3.6 "; 142: X = 3.6 + Y; 143: cout<<endl<<"X = 3.6 + Y: "; 144: X.Print(); 145: cout<<" = 3.6 + "; 146: Y.Print(); 147: X = 3.8 - Z; 148: cout<<endl<<"X = 3.8 - Z: "; 149: X.Print(); 150: cout<<" = 3.8 - "; 151: Z.Print(); 152: X = Z - 3.8; 153: cout<<endl<<"X = Z - 3.8: "; 154: X.Print(); 155: cout<<" = "; 156: Z.Print(); 157: cout<<" - 3.8 "; 158: return 0; 159: }

Chng ta chy v d 4.3, kt qu hnh 4.7

139

Hnh 4.7: Kt qu ca v d 4.3

4.6 A NNG HA CC TON T MT NGI


Cc ton t mt ngi c a nng ha trong hnh 4.8 sau: Ton t + * & -> V d +c -c *c &c c-> Ton t ~ ! ++ -V d ~c !a ++c, c++ --c, c--

Hnh 4.8: Cc ton t mt ngi c a nng ha Mt ton t mt ngi ca lp c a nng ha nh mt hm thnh vin khng tnh vi khng c tham s hoc nh mt hm khng thnh vin vi mt tham s; Tham s phi hoc l mt i tng lp hoc l mt tham chiu n i tng lp. V d 4.4: Ly li v d 4.3 v thm ton t du tr mt ngi.
CT4_4.CPP

1: #include <iostream.h> 2: #include <math.h> 3: 4: class Complex 5: {

140

6: private: 7: double Real,Imaginary; 8: public: 9: Complex(); // Constructor mc nh 10: Complex(double R,double I); 11: Complex (const Complex & Z); // Constructor sao chp 12: Complex (double R); // Constructor chuyn i 13: void Print(); // Hin th s phc 14: // Cc ton t tnh ton 15: friend Complex operator + (Complex Z1,Complex Z2); 16: friend Complex operator - (Complex Z1,Complex Z2); 17: Complex operator += (Complex Z); 18: Complex operator -= (Complex Z); 19: // Ton t tr mt ngi 20: Complex operator (); 21: // Cc ton t so snh 22: friend int operator == (Complex Z1,Complex Z2); 23: friend int operator != (Complex Z1,Complex Z2); 24: friend int operator > (Complex Z1,Complex Z2); 25: friend int operator >= (Complex Z1,Complex Z2); 26: friend int operator < (Complex Z1,Complex Z2); 27: friend int operator <= (Complex Z1,Complex Z2); 28: private: 29: double Abs(); // Gi tr tuyt i ca s phc 30: }; 31: 32: Complex::Complex()

141

33: { 34: Real = 0.0; 35: Imaginary = 0.0; 36: } 37: 38: Complex::Complex(double R,double I) 39: { 40: Real = R; 41: Imaginary = I; 42: } 43: 44: Complex::Complex(const Complex & Z) 45: { 46: Real = Z.Real; 47: Imaginary = Z.Imaginary; 48: } 49: 50: Complex::Complex(double R) 51: { 52: Real = R; 53: Imaginary = 0.0; 54: } 55: 56: void Complex::Print() 57: { 58: cout<<'('<<Real<<','<<Imaginary<<')'; 59: }

142

60: 61: Complex operator + (Complex Z1,Complex Z2) 62: { 63: Complex Tmp; 64: 65: Tmp.Real = Z1.Real + Z2.Real; 66: Tmp.Imaginary = Z1.Imaginary + Z2.Imaginary; 67: return Tmp; 68: } 69: 70: Complex operator - (Complex Z1,Complex Z2) 71: { 72: Complex Tmp; 73: 74: Tmp.Real = Z1.Real - Z2.Real; 75: Tmp.Imaginary = Z1.Imaginary - Z2.Imaginary; 76: return Tmp; 77: } 78: 79: Complex Complex::operator += (Complex Z) 80: { 81: Real += Z.Real; 82: Imaginary += Z.Imaginary; 83: return *this; 84: } 85: 86: Complex Complex::operator -= (Complex Z)

143

87: { 88: Real -= Z.Real; 89: Imaginary -= Z.Imaginary; 90: return *this; 91: } 92: 93: Complex Complex::operator - () 94: { 95: Complex Tmp; 96: 97: Tmp.Real = -Real; 98: Tmp.Imaginary = -Imaginary; 99: return Tmp; 100: } 101 102: int operator == (Complex Z1,Complex Z2) 103: { 104: return (Z1.Real == Z2.Real) && (Z1.Imaginary == Z2.Imaginary); 105: } 106: 107: int operator != (Complex Z1,Complex Z2) 108: { 109: return (Z1.Real != Z2.Real) || (Z1.Imaginary != Z2.Imaginary); 110: } 111: 112: int operator > (Complex Z1,Complex Z2)

144

113: { 114: return Z1.Abs() > Z2.Abs(); 115: } 116: 117: int operator >= (Complex Z1,Complex Z2) 118: { 119: return Z1.Abs() >= Z2.Abs(); 120: } 121: 122: int operator < (Complex Z1,Complex Z2) 123: { 124: return Z1.Abs() < Z2.Abs(); 125: } 126: 127: int operator <= (Complex Z1,Complex Z2) 128: { 129: return Z1.Abs() <= Z2.Abs(); 130: } 131: 132: double Complex::Abs() 133: { 134: return sqrt(Real*Real+Imaginary*Imaginary); 135: } 136: 137: int main() 138: { 139: Complex X, Y(4.3,8.2), Z(3.3,1.1);

145

140: 141: cout<<"X: "; 142: X.Print(); 143: cout<<endl<<"Y: "; 144: Y.Print(); 145: cout<<endl<<"Z: "; 146: Z.Print(); 147: X = -Y + 3.6; 148: cout<<endl<<endl<<"X = -Y + 3.6: "; 149: X.Print(); 150: cout<<" = "; 151: (-Y).Print(); 152: cout<<" + 3.6 "; 153: X = -Y + -Z; 154: cout<<endl<<"X = -Y + -Z: "; 155: X.Print(); 156: cout<<" = "; 157: (-Y).Print(); 158: cout<<" + "; 159: (-Z).Print(); 160: return 0; 161: }

Chng ta chy v d 4.4, kt qu hnh 4.9

146

Hnh 4.9: Kt qu ca v d 4.4

4.7 A NNG HA MT S TON T C BIT


Trong phn ny chng ta s tm hiu cch ci t mt vi ton t c bit nh () [] ++ -- , = -> 4.7.1 Ton t []: Khi ci t cc lp vector hoc chui k t, chng ta cn phi truy cp n tng phn t ca chng, trong ngn ng C/C++ c ton t [] truy cp n mt phn t ca mng. y l ton t hai ngi, c dng a[b] v khi a nng ton t ny th hm ton t tng ng phi l thnh vin ca mt lp. V d 4.5: a nng ha ton t [] truy cp n mt phn t ca vector.
CT4_5.CPP

1: #include <iostream.h> 2: 3: class Vector 4: { 5: private: 6: int Size; 7: int *Data; 8: public: 9: Vector(int S=2,int V=0); 10: ~Vector(); 11: void Print() const; 12: int & operator [] (int I); 13: }; 14:

147

15: Vector::Vector(int S,int V) 16: { 17: Size = S; 18: Data=new int[Size]; 19: for(int I=0;I<Size;++I) 20: Data[I]=V; 21: } 22: 23: Vector::~Vector() 24: { 25: delete []Data; 26: } 27: void Vector::Print() const 28: { 29: cout<<"Vector:("; 30: for(int I=0;I<Size-1;++I) 31: cout<<Data[I]<<","; 32: cout<<Data[Size-1]<<")"<<endl; 33: } 34: 35: int & Vector::operator [](int I) 36: { 37: return Data[I]; 38: } 39: 40: int main() 41: {

148

42: Vector V(5,1); 43: V.Print(); 44: for(int I=0;I<5;++I) 45: V[I]*=(I+1); 46: V.Print(); 47: V[0]=10; 48: V.Print(); 49: return 0; 50: }

Chng ta chy v d 4.5, kt qu hnh 4.10

Hnh 4.10: Kt qu ca v d 4.5 Trong chng trnh v d 4.5, hm ton t ca ton t [] lp Vector tr v mt tham chiu v ton t ny c th dng v tri ca php gn. 4.7.2 Ton t () Ton t () c dng gi hm, ton t ny gm hai ton hng: ton hng u tin l tn hm, ton hng th hai l danh sch cc tham s ca hm. Ton t ny c dng ging nh ton t [] v khi a nng ton t ny th hm ton t tng ng phi l thnh vin ca mt lp. V d 4.6: Ly li v d 4.5 nhng a nng ha ton t () truy cp n mt phn t ca vector.
CT4_6.CPP

1: #include <iostream.h> 2: 3: class Vector 4: {

149

5: private: 6: int Size; 7: int *Data; 8: public: 9: Vector(int S=2,int V=0); 10: ~Vector(); 11: void Print() const; 12: int & operator () (int I); 13: }; 14: 15: Vector::Vector(int S,int V) 16: { 17: Size = S; 18: Data=new int[Size]; 19: for(int I=0;I<Size;++I) 20: Data[I]=V; 21: } 22: 23: Vector::~Vector() 24: { 25: delete []Data; 26: } 27: void Vector::Print() const 28: { 29: cout<<"Vector:("; 30: for(int I=0;I<Size-1;++I) 31: cout<<Data[I]<<",";

150

32: cout<<Data[Size-1]<<")"<<endl; 33: } 34: 35: int & Vector::operator ()(int I) 36: { 37: return Data[I]; 38: } 39: 40: int main() 41: { 42: Vector V(5,1); 43: V.Print(); 44: for(int I=0;I<5;++I) 45: V(I)*=(I+1); 46: V.Print(); 47: V(0)=10; 48: V.Print(); 49: return 0; 50: }

Chng ta chy v d 4.6, kt qu hnh 4.11

Hnh 4.11: Kt qu ca v d 4.6 V d 4.7: a nng ha ton t () truy cp n phn t ca ma trn. 151

CT4_7.CPP

1: #include <iostream.h> 2: 3: class Matrix 4: { 5: private: 6: int Rows,Cols; 7: int **Data; 8: public: 9: Matrix(int R=2,int C=2,int V=0); 10: ~Matrix(); 11: void Print() const; 12: int & operator () (int R,int C); 13: }; 14: 15: Matrix::Matrix(int R,int C,int V) 16: { 17: int I,J; 18: Rows=R; 19: Cols=C; 20: Data = new int *[Rows]; 21: int *Temp=new int[Rows*Cols]; 22: for(I=0;I<Rows;++I) 23: { 24: Data[I]=Temp; 25: Temp+=Cols; 26: } 27: for(I=0;I<Rows;++I)

152

28: for(J=0;J<Cols;++J) 29: Data[I][J]=V; 30: } 31: 32: Matrix::~Matrix() 33: { 34: delete [] Data[0]; 35: delete [] Data; 36: } 37: 38: void Matrix::Print() const 39: { 40: int I,J; 41: for(I=0;I<Rows;++I) 42: { 43: for(J=0;J<Cols;++J) 44: { 45: cout.width(5); // Hin th canh l phi vi chiu di 5 k t 46: cout<<Data[I][J]; 47: } 48: cout<<endl; 49: } 50: } 51: 52: int & Matrix::operator () (int R,int C) 53: { 54: return Data[R][C];

153

55: } 56: 57: int main() 58: { 59: int I,J; 60: Matrix M(2,3,1); 61: cout<<"Matrix:"<<endl; 62: M.Print(); 63: for(I=0;I<2;++I) 64: for(J=0;J<3;++J) 65: M(I,J)*=(I+J+1); 66: cout<<"Matrix:"<<endl; 67: M.Print(); 68: return 0; 69: }

Chng ta chy v d 4.7, kt qu hnh 4.12

Hnh 4.12: Kt qu ca v d 4.7 4.7.3 Ton t ++ v -Ci t cc php ton ++ v -- cng tng t nh cc ton t khc. V d 4.8: a nng ha ton t ++ v -154

CT4_8.CPP

1: #include <iostream.h> 2: 3: class Point 4: { 5: private: 6: int X,Y; 7: public: 8: Point(int A=0,int B=0); 9: Point operator ++(); 10: Point operator --(); 11: void Print() const; 12: }; 13: 14: Point::Point(int A,int B) 15: { 16: X = A; 17: Y = B; 18: } 19: 20: Point Point::operator++() 21: { 22: ++X; 23: ++Y; 24: return *this; 25: } 26: 27: Point Point::operator--()

155

28: { 29: --X; 30: --Y; 31: return *this; 32: } 33: 34: void Point::Print() const 35: { 36: cout<<"X="<<X<<",Y="<<Y<<endl; 37: } 38: 39: int main() 40: { 41: Point P1(2,6),P2(5,8); 42: cout<<"Point 1:"; 43: P1.Print(); 44: cout<<"Point 2:"; 45: P2.Print(); 46: ++P1; 47: --P2; 48: cout<<"Point 1:"; 49: P1.Print(); 50: cout<<"Point 2:"; 51: P2.Print(); 52: return 0; 53: }

156

Chng ta chy v d 4.8, kt qu hnh 4.13

Hnh 4.13: Kt qu ca v d 4.8 Tuy nhin v d 4.8, khng phn bit c cc ton t ++ v -- khi dng tin t v hu t. c th phn bit c tin t v hu t khi a nng ha, ton t ++a (hoc --a) l ton t mt ngi, cn ton t a++ (hoc a--) c xem l ton t hai ngi trong ton hng th hai kiu int. V d 4.9: a nng ha ton t ++ v c phn bit tin t v hu t.
CT4_9.CPP

1: #include <iostream.h> 2: 3: class Point 4: { 5: private: 6: int X,Y; 7: public: 8: Point(int A=0,int B=0); 9: Point operator ++(); 10: Point operator ++(int); //Hu t 11: Point operator --(); //Tin t 12: Point operator --(int); //Hu t 13: void Print() const; 14: }; 15: 16: Point::Point(int A,int B) 17: {

157

18: X = A; 19: Y = B; 20: } 21: 22: Point Point::operator++() 23: { 24: ++X; 25: ++Y; 26: return *this; 27: } 28: 29: Point Point::operator++(int) 30: { 31: Point Tmp=*this; //Sao chp i tng ang xt vo i tng 32: //tm thi trc khi thay i 33: ++X; 34: ++Y; 35: return Tmp; 36: } 37: 38: Point Point::operator--() 39: { 40: --X; 41: --Y; 42: return *this; 43: } 44:

158

45: Point Point::operator--(int) 46: { 47: Point Tmp=*this; //Sao chp i tng ang xt vo i tng 48: //tm thi trc khi thay i 49: --X; 50: --Y; 51: return Tmp; 52: } 53: 54: void Point::Print() const 55: { 56: cout<<"X="<<X<<",Y="<<Y<<endl; 57: } 58: 59: int main() 60: { 61: Point P1(2,6),P2(5,8),P3,P4; 62: cout<<"Point 1:"; 63: P1.Print(); 64: cout<<"Point 2:"; 65: P2.Print(); 66: cout<<"Point 3:"; 67: P3.Print(); 68: cout<<"Point 4:"; 69: P4.Print(); 70: P3=++P1; 71: P4=P2++;

159

72: cout<<"Point 1:"; 73: P1.Print(); 74: cout<<"Point 2:"; 75: P2.Print(); 76: cout<<"Point 3:"; 77: P3.Print(); 78: cout<<"Point 4:"; 79: P4.Print(); 80: return 0; 81: }

Chng ta chy v d 4.9, kt qu hnh 4.14

Hnh 4.14: Kt qu ca v d 4.9 4.7.4 Ton t du phy Ton t du phy l ton t hai ngi. Chng ta c th a nng ha ton t du phy c ngha ty thch. Tuy nhin, nu mun a nng ha ton t phy c ngha tng t nh ton t phy bnh thng, chng ta cn b qua ton hng bn tri du phy (ngha l i tng m qua hm ton t tng ng c gi) v tr v i tng bn phi du phi nh l kt qu ca ton t. Do vy trong mt danh sch gm cc biu thc c ngn cch bi cc du phy, mi ton hng tr ton hng ngoi cng bn phi u b b qua. V d 4.10: a nng ha ton t du phy.
CT4_10.CPP

160

1: #include <iostream.h> 2: 3: class Point 4: { 5: private: 6: int X,Y; 7: public: 8: Point(int A=0,int B=0); 9: Point operator +(Point P); 10: Point operator ,(Point P); 11: void Print() const; 12: }; 13: 14: Point::Point(int A,int B) 15: { 16: X = A; 17: Y = B; 18: } 19: 20: Point Point::operator+(Point P) 21: { 22: Point Tmp; 23: Tmp.X=X+P.X; 24: Tmp.Y=Y+P.Y; 25: return Tmp; 26: } 27:

161

28: Point Point::operator,(Point P) 29: { 30: Point Tmp; 31: Tmp.X=P.X; 32: Tmp.Y=P.Y; 33: cout<<P.X<<" "<<P.Y<<endl; 34: return Tmp; 35: } 36: 37: void Point::Print() const 38: { 39: cout<<"X="<<X<<",Y="<<Y<<endl; 40: } 41: 42: int main() 43: { 44: Point P1(2,6),P2(5,20),P3(1,1); 45: cout<<"Point 1:"; 46: P1.Print(); 47: cout<<"Point 2:"; 48: P2.Print(); 49: cout<<"Point 3:"; 50: P3.Print(); 51: P1=(P1,P1+P2,P3); 52: cout<<"Point 1:"; 53: P1.Print(); 54: return 0;

162

55: }

Chng ta chy v d 4.10, kt qu hnh 4.15

Hnh 4.15: Kt qu ca v d 4.10 4.7.5 Ton t -> Ton t du mi tn -> (hoc ton t con tr cu trc) cho php chng ta truy cp thnh vin ca i tng thuc class, struct v union khi c p dng vo con tr ch n i tng . Chng ta c th a nng ha ton t ny, hm ton t ca ton t -> phi l hm thnh vin ca lp. Nu ton t -> c dng a-> th hm ton t l a.operator->() V d 4.11: a nng ha ton t ->.
CT4_11.CPP

1: #include <iostream.h> 2: 3: class MyClass 4: { 5: public: 6: int Data; 7: MyClass * operator ->() 8: { 9: return this; 10: } 11: }; 12:

163

13: int main() 14: { 15: MyClass M; 16: M->Data = 10; 17: cout<<M.Data<<" "<<M->Data; 18: return 0; 19: }

Chng ta chy v d 4.11, kt qu hnh 4.16

Hnh 4.16: Kt qu ca v d 4.11 Khi a nng ha ton t ->, C++ quy nh hm ton t ca n phi tr v: Hoc l con tr tr n i tng thuc lp cha thnh vin d liu cn truy cp (lp m trong hm ton t c nh ngha). Mt ton t -> bnh thng s c trnh bin dch t ng p dng vo con tr y truy cp thnh vin d liu ca i tng. Hoc l i tng thuc lp khc. Lp ny phi cha nh ngha hm ton t. Trnh bin dch s t ng p dng ton t -> trn i tng c tr v.Kt qu thu c c th l mt con tr tr n i tng hoc mt i tng. C th, chng ta c s din dch theo li quy cho ti khi no kt qu l mt con tr tr n i tng thuc lp cha thnh vin d liu cn truy cp. V d 4.12: Minh ha qu trnh din dch quy khi a nng ha ton t ->.
CT4_12.CPP

1: #include <iostream.h> 2: #include <string.h> 3: #include <stdlib.h> 4: 5: class String 6: {

164

7: public: 8: char *St; 9: String(char *S) 10: { 11: St=strdup(S); 12: } 13: ~String() 14: { 15: free(St); 16: } 17: }; 18: 19: class StringPointer 20: { 21: private: 22: String *M; 23: public: 24: StringPointer(String &S):M(&S) 25: { 26: } 27: String * operator ->() 28: { 29: return M; 30: } 31: }; 32: 33: int main()

165

34: { 35: StringPointer X(String("Chuc cac ban may man!")); 36: cout<<X->St; 37: return 0; 38: }

Chng ta chy v d 4.12, kt qu hnh 4.17

Hnh 4.17: Kt qu ca v d 4.12

4.7.6 Ton t gn Chng ta c th a nng ha ton t gn (=) nhng hm ton t ca n phi l hm thnh vin ca lp. Nu ton t gn c dng a=b th hm ton t c dng a.operator(b). V d 4.13: a nng ha ton t gn.
CT4_13.CPP

1: #include <iostream.h> 2: #include <string.h> 3: 4: class String 5: { 6: private: 7: char *St; 8: int Len; 9: public: 10: String(char *S); 166

11: ~String(); 12: char *GetStr(); 13: String & operator=(String &Obj); 14: }; 15: 16: String::String(char *S) 17: { 18: Len=strlen(S); 19: St=new char[Len+1]; 20: strcpy(St,S); 21: } 22: 23: String::~String() 24: { 25: delete []St; 26: } 27: 28: char * String::GetStr() 29: { 30: return St; 31: } 32: 33: String & String::operator=(String &Obj) 34: {

167

35: if (Len< Obj.Len) 36: { 37: delete [] St; 38: St=new char[Obj.Len+1]; 39: } 40: Len=Obj.Len; 41: strcpy(St,Obj.St); 42: return *this; 43: } 44: 45: int main() 46: { 47: String S1("Hello"), S2("Chao"); 48: cout<<"S1="<<S1.GetStr()<<endl; 49: cout<<"S2="<<S2.GetStr()<<endl; 50: S2=S1; 51: cout<<"S1="<<S1.GetStr()<<endl; 52: cout<<"S2="<<S2.GetStr()<<endl; 53: return 0; 54: }

Chng ta chy v d 4.13, kt qu hnh 4.18

168

Hnh 4.18: Kt qu ca v d 4.13

4.8 TON T CHUYN I KIU


Phn ln cc chng trnh x l thng tin s a dng ca cc kiu. i khi tt c cc thao tc "dng li bn trong mt kiu". Chng hn, mt s nguyn vi mt s nguyn to thnh mt s nguyn (min l kt qu khng qu ln c biu din nh mt s nguyn). Nhng tht cn thit chuyn i d liu ca mt kiu ti d liu ca kiu khc. iu ny c th xy ra trong cc php gn, cc kt qu tnh ton, trong vic chuyn cc gi tr ti hm, v trong vic tr v tr t hm. Trnh bin dch bit lm th no thc hin cc chuyn i no trong s cc kiu c sn. Cc lp trnh vin c th p buc cc chuyn i trong s cc kiu c sn bi p kiu. Nhng i vi cc kiu do ngi dng nh ngha th trnh bin dch khng th t ng bit lm th no chuyn i trong s cc kiu d liu do ngi dng nh ngha v cc kiu c sn. Lp trnh vin phi ch r lm sao cc chuyn i nh vy s xut hin. Cc chuyn i nh th c th c thc hin vi constructor chuyn i. Mt ton t chuyn i kiu c th c s dng chuyn i mt i tng ca mt lp thnh i tng ca mt lp khc hoc thnh mt i tng ca mt kiu c sn. Ton t chuyn i kiu nh th phi l hm thnh vin khng tnh v khng l hm friend. Prototype ca hm thnh vin ny c c php: operator <data type> (); V d 4.14: Ton t chuyn i kiu
CT4_14.CPP

1: #include <iostream.h> 2: 3: class Number 4: { 5: private: 6: float Data; 7: public: 8: Number(float F=0.0) 9: {

169

10: Data=F; 11: } 12: operator float() 13: { 14: return Data; 15: } 16: operator int() 17: { 18: return (int)Data; 19: } 20: }; 21: 22: int main() 23: { 24: Number N1(9.7), N2(2.6); 25: float X=(float)N1; //Gi operator float() 26: cout<<X<<endl; 27: int Y=(int)N2; //Gi operator int() 28: cout<<Y<<endl; 29: return 0; 30: }

Chng ta chy v d 4.14, kt qu hnh 4.19

Hnh 4.19: Kt qu ca v d 4.14 170

4.9 TON T NEW V DELETE


Cc ton t new v delete ton cc c th c a nng ha. iu ny cho php cc lp trnh vin C++ c kh nng xy dng mt h thng cp pht b nh theo ngi dng, ci cng giao tip nh h thng cp pht mc nh. C hai cch a nng ha cc ton t new v delete: Chng ta c th a nng ha mt cch ton cc ngha l thay th hn cc ton t new v delete mc nh. Chng ta nng ha cc ton t new v delete vi t cch l hm thnh vin ca lp nu mun cc ton t new v delete p dng i vi lp . Khi chng ta dng new v delete i vi lp no , trnh bin dch s kim tra xem new v delete c c nh ngha ring cho lp hay khng; nu khng th dng new v delete ton cc (c th c a nng ha). Hm ton t ca ton t new v delete c prototype nh sau: void * operator new(size_t size); void operator delete(void * ptr); Trong tham s kiu size_t c trnh bin dch hiu l kch thc ca kiu d liu c trao cho ton t new. 4.9.1 a nng ha ton t new v delete ton cc: V d 4.15: a nng ha ton t new v delete ton cc ng thi chng t rng ton t new v delete do a nng ha thay th ton t new v delete mc nh.
CT4_15.CPP

1: #include <iostream.h> 2: #include <stdlib.h> 3: 4: class Point 5: { 6: private: 7: int X, Y; 8: public: 9: Point(int A=0,int B=0) 10: {

171

11: X=A; 12: Y=B; 13: cout<<"Constructor!"<<endl; 14: } 15: ~Point() 16: { 17: cout<<"Destructor!"<<endl; 18: } 19: void Print() const 20: { 21: cout<<"X="<<X<<","<<"Y="<<Y<<endl; 22: } 23: }; 24: 25: void * operator new(size_t Size) 26: { 27: return malloc(Size); 28: } 29: 30: void operator delete(void *Ptr) 31: { 32: free(Ptr); 33: } 34: 35: int main() 36: { 37: Point *P1,*P2;

172

38: P1= new Point(10,20); 39: if (P1==NULL) 40: { 41: cout<<"Out of memory!"<<endl; 42: return 1; 43: } 44: P2= new Point(-10,-20); 45: if (P2==NULL) 46: { 47: cout<<"Out of memory!"<<endl; 48: return 1; 49: } 50: int *X=new int; 51: if (X==NULL) 52: { 53: cout<<"Out of memory!"<<endl; 54: return 1; 55: } 56: *X=10; 57: cout<<"X="<<*X<<endl; 58: cout<<"Point 1:"; 59: P1->Print(); 60: cout<<"Point 2:"; 61: P2->Print(); 62: delete P1; 63: delete P2; 64: delete X;

173

65: return 0; 66: }

Chng ta chy v d 4.15, kt qu hnh 4.20

Hnh 4.20: Kt qu ca v d 4.15 4.9.2 a nng ha ton t new v delete cho mt lp: Nu mun ton t new v delete c tnh cht c bit ch khi p dng cho i tng ca lp no , chng ta c th a nng ha ton t new v delete vi t cch l hm thnh vin ca lp . Vic ny khng khc lm so vi cch a nng ha ton t new v delete mt cch ton cc. V d 4.16: a nng ha ton t new v delete cho mt lp.
CT4_16.CPP

1: #include <iostream.h> 2: #include <stdlib.h> 3: class Number 4: { 5: private: 6: int Data; 7: public: 8: Number(int X=0) 9: { 10: Data=X;

174

11: } 12: 13: void * operator new(size_t Size) 14: { 15: cout<<"Toan tu new cua lop!"<<endl; 16: return ::new unsigned char[Size]; 17: } 18: 19: void operator delete(void *Ptr) 20: { 21: cout<<"Toan tu delete cua lop!"<<endl; 22: ::delete Ptr; 23: } 24: 25: void Print() const 26: { 27: cout<<"Data:"<<Data<<endl; 28: } 29: 30: }; 31: 32: int main() 33: { 34: Number *N; 35: N= new Number(10); 36: if (N==NULL) 37: {

175

38: cout<<"Out of memory!"<<endl; 39: return 1; 40: } 41: int *X=new int; 42: if (X==NULL) 43: { 44: cout<<"Out of memory!"<<endl; 45: return 1; 46: } 47: *X=10; 48: cout<<"X="<<*X<<endl; 49: N->Print(); 50: delete N; 51: delete X; 52: return 0; 53: }

Chng ta chy v d 4.16, kt qu hnh 4.21

Hnh 4.21: Kt qu ca v d 4.16

4.10 A NNG HA CC TON T CHN DNG << V TRCH DNG >>


Chng ta c th a nng ha cc ton t chn dng << (stream insertion) v trch dng >> (stream extraction). Hm ton t ca ton t << c a nng ha c prototype nh sau: ostream & operator << (ostream & stream, ClassName Object); 176

Hm ton t << tr v tham chiu ch n dng xut ostream. Tham s th nht ca hm ton t << l mt tham chiu ch n dng xut ostream, tham s th hai l i tng c chn vo dng. Khi s dng, dng trao cho ton t << (tham s th nht) l ton hng bn tri v i tng c a vo dng (tham s th hai) l ton hng bn phi. bo m cch dng ton t << lun nht qun, chng ta khng th nh ngha hm ton t << nh l hm thnh vin ca lp ang xt, thng thng n chnh l hm friend. Cn hm ton t ca ton t >> c a nng ha c prototype nh sau: istream & operator >> (istream & stream, ClassName Object); Hm ton t >> tr v tham chiu ch n dng nhp istream. Tham s th nht ca hm ton t ny l mt tham chiu ch n dng nhp istream, tham s th hai l i tng ca lp ang xt m chng ta mun to dng nh vo d liu ly t dng nhp. Khi s dng, dng nhp ng vai ton hng bn tri, i tng nhn d liu ng vai ton hng bn phi. Cng nh trng hp ton t <<, hm ton t >> khng l hm thnh vin ca lp, thng thng n chnh l hm friend. V d 4.17:
CT4_17.CPP

1: #include <iostream.h> 2: 3: class Point 4: { 5: private: 6: int X,Y; 7: public: 8: Point(); 9: friend ostream & operator << (ostream & Out,Point & P); 10: friend istream & operator >> (istream & In,Point & P); 11: }; 12: 13: Point::Point() 14: { 15: X=Y=0; 16: } 17:

177

18: ostream & operator << (ostream & Out,Point & P) 19: { 20: Out<<"X="<<P.X<<",Y="<<P.Y<<endl; 21: return Out; //Cho php cout<<a<<b<<c; 22: } 23: 24: istream & operator >> (istream &In,Point & P) 25: { 26: cout<<"X:"; 27: In>>P.X; 28: cout<<"Y:"; 29: In>>P.Y; 30: return In; //Cho php cin>>a>>b>>c; 31: } 32: 33: int main() 34: { 35: Point P; 36: cin>>P; 37: cout<<"Point:"<<P; 38: return 0; 39: }

Chng ta chy v d 4.17, kt qu hnh 4.22

178

Hnh 4.22: Kt qu ca v d 4.17

4.11 MT S V D
4.11.1 Lp String V d 4.18: Chng ta s xy dng mt lp x l vic to v thao tc trn cc chui (string). C++ khng ci sn kiu d liu chui. Nhng C++ cho php chng ta thm kiu chui nh mt lp thng qua c ch a nng ha.
CT4_18.CPP

1: #include <iostream.h> 2: #include <iomanip.h> 3: #include <string.h> 4: #include <assert.h> 5: 6: class String 7: { 8: private: 9: char *Ptr; //Con tr tr n im bt u ca chui 10: int Length; //Chiu di chui 11: public: 12: String(const char * = ""); //Constructor chuyn i 13: String(const String &); //Constructor sao chp 14: ~String(); //Destructor 15: const String &operator=(const String &); //Php gn 16: String &operator+=(const String &); 17: int operator!() const; //Php ni

//Kim tra chui rng

18: int operator==(const String &) const; 19: int operator!=(const String &) const; 20: int operator<(const String &) const; 21: int operator>(const String &) const;

179

22: int operator>=(const String &) const; 23: int operator<=(const String &) const; 24: char & operator[](int); //Tr v k t tham chiu 25: String &operator()(int, int); //Tr v mt chui con 26: int GetLength() const; 27: friend ostream &operator<<(ostream &, const String &); 28: friend istream &operator>>(istream &, String &); 29: }; 30: 31: //Constructor sao chp: Chuyn i char * thnh String 32: String::String(const char *S) 33: { 34: cout << "Conversion constructor: " << S << endl; 35: Length = strlen(S); 36: Ptr = new char[Length + 1]; 37: assert(Ptr != 0); 38: strcpy(Ptr, S); 39: } 40: 41: String::String(const String &Copy) 42: { 43: cout << "Copy constructor: " << Copy.Ptr << endl; 44: Length = Copy.Length; 45: Ptr = new char[Length + 1]; 46: assert(Ptr != 0); 47: strcpy(Ptr, Copy.Ptr); 48: }

180

49: 50: //Destructor 51: String::~String() 52: { 53: cout << "Destructor: " << Ptr << endl; 54: delete [] Ptr; 55: } 56: 57: const String &String::operator=(const String &Right) 58: { 59: cout << "operator= called" << endl; 60: if (&Right != this) 61: { 62: delete [] Ptr; 63: Length = Right.Length; 64: Ptr = new char[Length + 1]; 65: assert(Ptr != 0); 66: strcpy(Ptr, Right.Ptr); 67: } 68: else 69: cout << "Attempted assignment of a String to itself" << endl; 70: return *this; 71: } 72: 73: String &String::operator+=(const String &Right) 74: { 75: char *TempPtr = Ptr;

181

76: Length += Right.Length; 77: Ptr = new char[Length + 1]; 78: assert(Ptr != 0); 79: strcpy(Ptr, TempPtr); 80: strcat(Ptr, Right.Ptr); 81: delete [] TempPtr; 82: return *this; 83: } 84: 85: int String::operator!() const 86: { 87: return Length == 0; 88: } 89: 90: int String::operator==(const String &Right) const 91: { 92: return strcmp(Ptr, Right.Ptr) == 0; 93: } 94: 95: int String::operator!=(const String &Right) const 96: { 97: return strcmp(Ptr, Right.Ptr) != 0; 98: } 99: 100: int String::operator<(const String &Right) const 101: { 102: return strcmp(Ptr, Right.Ptr) < 0;

182

103: } 104: 105: int String::operator>(const String &Right) const 106: { 107: return strcmp(Ptr, Right.Ptr) > 0; 108: } 109: 110: int String::operator>=(const String &Right) const 111: { 112: return strcmp(Ptr, Right.Ptr) >= 0; 113: } 114: 115: int String::operator<=(const String &Right) const 116: { 117: return strcmp(Ptr, Right.Ptr) <= 0; 118: } 119: 120: char &String::operator[](int Subscript) 121: { 122: assert(Subscript >= 0 && Subscript < Length); 123: return Ptr[Subscript]; 124: } 125: 126: String &String::operator()(int Index, int SubLength) 127: { 128: assert(Index >= 0 && Index < Length && SubLength >= 0); 129: String *SubPtr = new String;

183

130: assert(SubPtr != 0); 131: if ((SubLength == 0) || (Index + SubLength > Length)) 132: SubPtr->Length = Length - Index + 1; 133: else 134: SubPtr->Length = SubLength + 1; 135: delete SubPtr->Ptr; 136: SubPtr->Ptr = new char[SubPtr->Length]; 137: assert(SubPtr->Ptr != 0); 138: strncpy(SubPtr->Ptr, &Ptr[Index], SubPtr->Length); 139: SubPtr->Ptr[SubPtr->Length] = '\0'; 140: return *SubPtr; 141: } 142: 143: int String::GetLength() const 144: { 145: return Length; 146: } 147: ostream &operator<<(ostream &Output, const String &S) 148: { 149: Output << S.Ptr; 150: return Output; 151: } 152: 153: istream &operator>>(istream &Input, String &S) 154: { 155: char Temp[100]; 156: Input >> setw(100) >> Temp;

184

157: S = Temp; 158: return Input; 159: } 160: 161: int main() 162: { 163: String S1("happy"), S2(" birthday"), S3; 164: cout << "S1 is \"" << S1 << "\"; S2 is \"" << S2 165: << "\"; S3 is \"" << S3 << '\"' << endl 166: << "The results of comparing S2 and S1:" << endl

167: << "S2 == S1 yields " << (S2 == S1) << endl 168: 169: 170: 171: 172: << "S2 != S1 yields " << (S2 != S1) << endl << "S2 > S1 yields " << (S2 > S1) << endl << "S2 < S1 yields " << (S2 < S1) << endl << "S2 >= S1 yields " << (S2 >= S1) << endl << "S2 <= S1 yields " << (S2 <= S1) << endl;

173: cout << "Testing !S3:" << endl; 174: if (!S3) 175: { 176: cout << "S3 is empty; assigning S1 to S3;" << endl; 177: S3 = S1; 178: cout << "S3 is \"" << S3 << "\"" << endl; 179: } 180: cout << "S1 += S2 yields S1 = "; 181: S1 += S2; 182: cout << S1 << endl; 183: cout << "S1 += \" to you\" yields" << endl;

185

184: S1 += " to you"; 185: cout << "S1 = " << S1 << endl; 186: cout << "The substring of S1 starting at" << endl 187: " 188: << "location 0 for 14 characters, S1(0, 14), is:

<< S1(0, 14) << endl;

189: cout << "The substring of S1 starting at" << endl 190: 191: << "location 15, S1(15, 0), is: " << S1(15, 0) <<endl; // 0 is "to end of string"

192: String *S4Ptr = new String(S1); 193: cout << "*S4Ptr = " << *S4Ptr <<endl; 194: cout << "assigning *S4Ptr to *S4Ptr" << endl; 195: *S4Ptr = *S4Ptr; 196: cout << "*S4Ptr = " << *S4Ptr << endl; 197: delete S4Ptr; 198: S1[0] = 'H'; 199: S1[6] = 'B'; 200: cout <<"S1 after S1[0] = 'H' and S1[6] = 'B' is: "<< S1 << endl; 201: cout << "Attempt to assign 'd' to S1[30] yields:" << endl; 202: S1[30] = 'd'; //Li: Ch s vt khi min!!! 203: return 0; 204: }

Chng ta chy v d 4.18, kt qu hnh 4.23

186

Hnh 4.23: Kt qu ca v d 4.18 4.11.1 Lp Date V d 4.19: 187

CT4_19.CPP

1: #include <iostream.h> 2: class Date 3: { 4: private: 5: int Month; 6: int Day; 7: int Year; 8: static int Days[]; //Mng cha s ngy trong thng 9: void HelpIncrement(); //Hm tng ngy ln mt 10: public: 11: Date(int M = 1, int D = 1, int Y = 1900); 12: void SetDate(int, int, int); 13: Date operator++(); //Tin t 14: Date operator++(int); //Hu t 15: const Date &operator+=(int); 16: int LeapYear(int); //Kim tra nm nhun 17: int EndOfMonth(int); //Kim tra cui thng 18: friend ostream &operator<<(ostream &, const Date &); 19: }; 20: 21: int Date::Days[] = {31, 28, 31, 30, 31, 30,31, 31, 30, 31, 30, 31}; 22: 23: Date::Date(int M, int D, int Y) 24: { 25: SetDate(M, D, Y); 188

26: } 27: 28: void Date::SetDate(int MM, int DD, int YY) 29: { 30: Month = (MM >= 1 && MM <= 12) ? MM : 1; 31: Year = (YY >= 1900 && YY <= 2100) ? YY : 1900; 32: if (Month == 2 && LeapYear(Year)) 33: Day = (DD >= 1 && DD <= 29) ? DD : 1; 34: else 35: Day = (DD >= 1 && DD <= Days[Month-1]) ? DD : 1; 36: } 37: 38: Date Date::operator++() 39: { 40: HelpIncrement(); 41: return *this; 42: } 43: Date Date::operator++(int) 44: { 45: Date Temp = *this; 46: HelpIncrement(); 47: return Temp; 48: } 49:

189

50: const Date &Date::operator+=(int AdditionalDays) 51: { 52: for (int I = 1; I <= AdditionalDays; I++) 53: HelpIncrement(); 54: return *this; 55: } 56: 57: int Date::LeapYear(int Y) 58: { 59: if (Y % 400 == 0 || (Y % 100 != 0 && Y % 4 == 0) ) 60: return 1; //Nm nhun 61: return 0; //Nm khng nhun 62: } 63: 64: int Date::EndOfMonth(int D) 65: { 66: if (Month == 2 && LeapYear(Year)) 67: return D == 29; 68: return D == Days[Month-1]; 69: } 70: 71: void Date::HelpIncrement() 72: { 73: if (EndOfMonth(Day) && Month == 12) //Ht nm

190

74: { 75: Day = 1; 76: Month = 1; 77: ++Year; 78: } 79: else 80: if (EndOfMonth(Day)) //Ht thng 81: { 82: Day = 1; 83: ++Month; 84: } 85: else 86: ++Day; 87: } 88: 89: ostream &operator<<(ostream &Output, const Date &D) 90: { 91: static char*MonthName[12]={"January","February","March","April","May", 92: ; "June","July", "August", "September", 93: ; "October","November", "December" 94: }; 95: 96: Output << MonthName[D.Month-1] << ' '<< D.Day << ", " << D.Year; 97: return Output;

191

98: } 99: 100: int main() 101: { 102: Date D1, D2(12, 27, 1992), D3(0, 99, 8045); 103: cout << "D1 is " << D1 << endl 104: 105: << "D2 is " << D2 << endl << "D3 is " << D3 << endl << endl;

106: cout << "D2 += 7 is " << (D2 += 7) << endl << endl; 107: D3.SetDate(2, 28, 1992); 108: cout << " D3 is " << D3 << endl; 109: cout << "++D3 is " << ++D3 << endl << endl; 110: Date D4(3, 18, 1969); 111: cout << "Testing the preincrement operator:" << endl 112: << " D4 is " << D4 << endl;

113: cout << "++D4 is " << ++D4 << endl; 114: cout << " D4 is " << D4 << endl << endl; 115: cout << "Testing the postincrement operator:" << endl 116: << " D4 is " << D4 << endl;

117: cout << "D4++ is " << D4++ << endl; 118: cout << " D4 is " << D4 << endl; 119: return 0; 120: }

Chng ta chy v d 4.19, kt qu hnh 4.24

192

Hnh 4.24: Kt qu ca v d 4.19

5.1 DN NHP
Trong chng ny v chng k, chng ta tm hiu hai kh nng m lp trnh hng i tng cung cp l tnh k tha (inheritance) v tnh a hnh (polymorphism). Tnh k tha l mt hnh thc ca vic s dng li phn mm trong cc lp mi c to t cc lp c bng cch "ht" cc thuc tnh v hnh vi ca chng v t im thm vi cc kh nng m cc lp mi i hi. Vic s dng li phn mm tit kim thi gian trong vic pht trin chng trnh. N khuyn khch s dng li phn mm cht lng cao th thch v g li, v th gim thiu cc vn sau khi mt h tr thnh chnh thc. Tnh a hnh cho php chng ta vit cc chng trnh trong mt kiu cch chung x l cc lp c lin h nhau. Tnh k tha v tnh a hnh cc k thut c hiu lc i vi s chia vi s phc tp ca phn mm. Khi to mt lp mi, thay v vit cc thnh vin d liu v cc hm thnh vin, lp trnh vin c th thit k m lp mi c k tha cc thnh vin d liu v cc hm thnh vin ca lp trc nh ngha l lp c s (base class). Lp mi c tham chiu l lp dn xut (derived class). Mi lp dn xut t n tr thnh mt ng c l mt lp c s cho lp dn xut tng lai no . Bnh thng mt lp dn xut thm cc thnh vin d liu v cc hm thnh vin, v th mt lp dn xut thng thng rng hn lp c s ca n. Mt lp dn xut c ch nh hn mt lp c s v biu din mt nhm ca cc i tng nh hn. Vi i tng n, lp dn xut, lp dn xut bt u bn ngoi thc cht ging nh lp c s. Sc mnh thc s ca s k tha l kh nng nh ngha trong lp dn xut cc phn thm, thay th hoc tinh lc cc c tnh k tha t lp c s. Mi i tng ca mt lp dn xut cng l mt i tng ca lp c s ca lp dn xut . Tuy nhin iu ngc li khng ng, cc i tng lp c s khng l cc i tng ca cc lp dn xut ca lp c s . Chng ta s ly mi quan h "i tng lp dn xut l mt i tng lp c s" thc hin cc thao tc quan trng no . Chng hn, chng ta c th lun mt s a dng ca cc i tng khc nhau c lin quan 193

thng qua s k tha thnh danh sch lin kt ca cc i tng lp c s. iu ny cho php s a dng ca cc i tng x l mt cch tng qut. Chng ta phn bit gia "l mt"(is a) quan h v "c mt" (has a) quan h. "l mt" l s k tha. Trong mt "l mt" quan h, mt i tng ca kiu lp dn xut cng c th c x l nh mt i tng ca kiu lp c s. "c mt" l s phc hp (composition). Trong mt "c mt" quan h, mt i tng lp c mt hay nhiu i tng ca cc lp khc nh l cc thnh vin, do lp bao cc i tng ny gi l lp phc hp (composed class).

5.2 K THA N
5.2.1 Cc lp c s v cc lp dn xut Thng mt i tng ca mt lp tht s l mt i tng ca lp khc cng c. Mt hnh ch nht l mt t gic, v th lp Rectangle c th k tha t lp Quadrilateral. Trong khung cnh ny, lp Quadrilateral gi l mt lp c s v lp Rectangle gi l mt lp dn xut. Hnh 5.1 cho chng ta mt vi v d v k tha n. Cc ngn ng lp trnh hng i tng nh SMALLTALK s dng thut ng khc: Trong k tha, lp c s c gi l lp cha (superclass), lp dn xut c gi l lp con (subclass). Lp c s Student Shape Lp dn xut GraduateStudent UndergraduateStudent Circle Triangle Rectangle CarLoan HomeImprovementLoan MortgageLoan FacultyMember StaffMember CheckingAcount SavingsAcount

Loan

Employee Acount

Hnh 5.1: Mt vi k tha n. S k tha hnh thnh cc cu trc phn cp ging cy (cn gi l cy ph h). Mt lp c s tn ti trong mt phn cp quan h vi lp dn xut ca n. Mt lp c th tn ti chc chn bi chnh n, nhng khi mt lp c s dng vi c ch ca s k tha th lp tr thnh hoc l mt lp c s m cung cp cc thuc tnh v cc hnh vi cho cc lp khc, hoc l lp tr thnh mt lp dn xut m k tha cc thuc tnh v cc hnh vi. Chng ta pht trin mt phn cp k tha n. Mt trng i hc cng ng c th c hng ngn ngi m l cc thnh vin cng ng. Nhng ngi ny gm cc ngi lm cng v cc sinh vin. Nhng ngi lm cng hoc l cc thnh vin khoa hoc cc thnh vin nhn vin. Cc thnh vin khoa hoc l cc nh qun l hoc ging vin. iu ny tr thnh phn cp k tha nh hnh 5.2

194

Hnh 5.2: Mt phn cp k tha cho cc thnh vin ca trng i hc cng ng. Phn cp k tha quan trng khc l phn cp Shape hnh 5.3.

Hnh 5.3: Phn cp lp Shape ch nh lp CommissionWorker c dn xut t lp Employee, lp CommissionWorker c nh ngha nh sau: class CommissionWorker: public Employee { . }; iu ny c gi l k tha public v l loi m phn ln c s dng. Ngoi ra chng ta cn c k tha private v k tha protected. Vi k tha public, cc thnh vin public v protected ca lp c s c k tha nh l cc thnh vin public v protected ca lp dn xut tng ng. Nn nh rng cc thnh vin private ca lp c s khng th truy cp t cc lp dn xut ca lp . 195

X l cc i tng lp c s v cc i tng lp dn xut tng t; ph bin l c biu din bng cc thuc tnh v cc hnh vi ca lp c s. Cc i tng ca bt k lp no dn xut t mt lp c s chung c th tt c c x l nh cc i tng ca lp c s . 5.2.2 Cc thnh vin protected: Cc thnh vin public ca mt lp c s c truy cp bi tt c cc hm trong chng trnh. Cc thnh vin private ca mt lp c s ch c truy cp bi cc hm thnh vin v cc hm friend ca lp c s. Truy cp protected phc v nh mt mc trung gian ca s bo v gia truy cp public v truy cp private. Cc thnh vin protected ca mt lp c s c th ch c truy cp bi cc hm thnh vin v cc hm friend ca lp c s v bi cc hm thnh vin v cc hm friend ca lp dn xut. Cc thnh vin lp dn xut k tha public c th tham kho ti cc thnh vin public v protected bng cch s dng cc tn thnh vin. 5.2.3 p kiu cc con tr lp c s ti cc con tr lp dn xut Mt i tng ca mt lp dn xut k tha public cng c th c x l nh mt i tng ca lp c s ca n tng ng. Nhng ngc li khng ng: mt i tng lp c s cng khng t ng l mt i tng lp dn xut. Tuy nhin, lp trnh vin s dng p kiu chuyn i mt con tr lp c s thnh mt con tr lp dn xut. V d 5.1: Chng trnh sau s c chia thnh nhiu file (gm cc file .H v .CPP) v to mt project c tn l CT5_1.PRJ gm cc file .cpp File POINT.H:
POINT.H

1: //POINT.H 2: //nh ngha lp Point 3: #ifndef POINT_H 4: #define POINT_H 5: 6: class Point 7: { 8: protected: 9: float X,Y;

196

10: public: 11: Point(float A= 0, float B= 0); 12: void SetPoint(float A, float B); 13: float GetX() const 14: { 15: return X; 16: } 17: float GetY() const 18: { 19: return Y; 20: } 21: friend ostream & operator <<(ostream &Output, const Point &P); 22: }; 23: 24: #endif

File POINT.CPP
POINT.CPP

1: //POINT.CPP 2: //nh ngha cc hm thnh vin ca lp Point 3: #include <iostream.h> 4: #include "point.h" 5: 6: Point::Point(float A, float B) 7: { 8: SetPoint(A, B);

197

9: } 10: 11: void Point::SetPoint(float A, float B) 12: { 13: X = A; 14: Y = B; 15: } 16: 17: ostream & operator <<(ostream &Output, const Point &P) 18: { 19: Output << '[' << P.X << ", " << P.Y << ']'; 20: return Output; 21: }

File CIRCLE.H
CIRCLE.H

1: //CIRCLE.H 2: //nh ngha lp Circle 3: #ifndef CIRCLE_H 4: #define CIRCLE_H 5: 6: #include "point.h" 7: class Circle : public Point 8: { 9: protected: 10: float Radius; 11: public:

198

12: Circle(float R = 0.0, float A = 0, float B = 0); 13: void SetRadius(float R); 14: float GetRadius() const; 15: float Area() const; 16: friend ostream & operator <<(ostream &Output, const Circle &C); 17: }; 18: 19: #endif

File CIRCLE.CPP
CIRCLE.CPP

1: //CIRCLE.CPP 2: //nh ngha cc hm thnh vin ca lp Circle 3: #include <iostream.h> 4: #include <iomanip.h> 5: #include "circle.h" 6: 7: Circle::Circle(float R, float A, float B): Point(A, B) 8: { 9: Radius = R; 10: } 11: 12: void Circle::SetRadius(float R) 13: { 14: Radius = R; 15: }

199

16: 17: float Circle::GetRadius() const 18: { 19: return Radius; 20: } 21: 22: float Circle::Area() const 23: { 24: return 3.14159 * Radius * Radius; 25: } 26: 27: //Xut mt Circle theo dng: Center = [x, y]; Radius = #.## 28: ostream & operator <<(ostream &Output, const Circle &C) 29: { 30: Output << "Center = [" << C.X << ", " << C.Y 31: << "]; Radius = " << setiosflags(ios::showpoint) 32: << setprecision(2) << C.Radius; 33: return Output; 34: }

File CT5_1.CPP:
CT5_1.CPP

1: //CT5_1.CPP 2: //Chng trnh 5.1: p cc con tr lp c s ti cc con tr lp dn xut 3: #include <iostream.h> 4: #include <iomanip.h>

200

5: #include "point.h" 6: #include "circle.h" 7: 8: int main() 9: { 10: Point *PointPtr, P(3.5, 5.3); 11: Circle *CirclePtr, C(2.7, 1.2, 8.9); 12: cout << "Point P: "<<P<<endl<<"Circle C: "<<C<< endl; 13 //X l mt Circle nh mt Point (ch xem mt phn lp c s) 14: PointPtr = &C; 15: cout << endl << "Circle C (via *PointPtr): "<<*PointPtr<<endl; 16 //X l mt Circle nh mt Circle 17: PointPtr = &C; 18: CirclePtr = (Circle *) PointPtr; 19: cout << endl << "Circle C (via *CirclePtr): " << endl 20: " 21: <<*CirclePtr<< endl << "Area of C (via CirclePtr):

<< CirclePtr->Area() << endl;

22: //Nguy him: Xem mt Point nh mt Circle 23: PointPtr = &P; 24: CirclePtr = (Circle *) PointPtr; 25: cout << endl << "Point P (via *CirclePtr): "<< endl 26: points to: " 27: 28: return 0; 29: } <<*CirclePtr<< endl << "Area of object CirclePtr

<<CirclePtr->Area() << endl;

201

Chng ta chy v d 5.1, kt qu hnh 5.4

Hnh 5.4: Kt qu ca v d 5.1 Trong nh ngha lp Point, cc thnh vin d liu X v Y c ch nh l protected, iu ny cho php cc lp dn xut t lp Point truy cp trc tip cc thnh vin d liu k tha. Nu cc thnh vin d liu ny c ch nh l private, cc hm thnh vin public ca Point phi c s dng truy cp d liu, ngay c bi cc lp dn xut. Lp Circle c k tha t lp Point vi k tha public ( dng 7 file CIRCLE.H), tt c cc thnh vin ca lp Point c k tha thnh lp Circle. iu ny c ngha l giao din public bao gm cc hm thnh vin public ca Point cng nh cc hm thnh vin Area(), SetRadius() v GetRadius(). Constructor lp Circle phi bao gm constructor lp Point khi ng phn lp c s ca i tng lp Circle dng 7 file CIRCLE.CPP, dng ny c th c vit li nh sau: Circle::Circle(float R, float A, float B) : Point(A, B) //Gi constructor ca lp c s Cc gi tr A v B c chuyn t constructor lp Circle ti constructor lp Point khi ng cc thnh vin X v Y ca lp c s. Nu constructor lp Circle khng bao gm constructor lp Point th constructor lp Point gi vi cc gi tr mc nh cho X v Y (ngha l 0 v 0). Nu lp Point khng cung cp mt constructor mc nh th trnh bin dch pht sinh li. Trong chng trnh chnh (file CT5_1.CPP) gn mt con tr lp dn xut (a ch ca i tng C) cho con tr lp c s PointPtr v xut i tng C ca Circle bng ton t chn dng ca lp Point ( dng 14 v 15). Ch rng ch phn Point ca i tng C ca Circle c hin th. N lun lun ng gn mt con tr lp dn xut cho con tr lp c s bi v mt i tng lp dn xut l mt i tng lp c s. Con tr lp c s ch trng thy phn lp c s ca i tng lp dn xut. Trnh bin dch thc hin mt chuyn i ngm ca con tr lp dn xut cho mt con tr lp c s. Sau chng trnh gn mt con tr lp dn xut (a ch ca i tng C) cho con tr lp c s PointPtr v p PointPtr tr v kiu Circle *. Kt qu ca p kiu c gn cho CirclePtr. i tng 202

C ca Circle c xut bng cch s dng ton t chn dng ca Circle. Din tch ca i tng C c xut thng qua CirclePtr. Cc kt qu ny l gi tr din tch ng bi v cc con tr lun lun c tr ti mt i tng Circle (t dng 17 n 22). K tip, chng trnh gn mt con tr lp c s (a ch ca i tng P) cho con tr lp c s PointPtr v p PointPtr tr v kiu Circle *. Kt qu ca p kiu c gn cho CirclePtr. i tng P c xut s dng ton t chn dng ca lp Circle. Ch rng gi tr xut ca thnh vin Radius "k l". Vic xut mt Point nh mt Circle a n mt gi tr khng hp l cho Radius bi v cc con tr lun c tr n mt i tng Point. Mt i tng Point khng c mt thnh vin Radius. V th, chng trnh xut gi tr "rc" i vi thnh vin d liu Radius. Ch rng gi tr ca din tch l 0.0 bi v tnh ton ny da trn gi tr khng tn ti ca Radius (t dng 23 n 27).R rng, truy cp cc thnh vin d liu m khng phi th nguy him. Gi cc hm thnh vin m khng tn ti c th ph hy chng trnh. 5.2.4 nh ngha li cc thnh vin lp c s trong mt lp dn xut: Mt lp dn xut c th nh ngha li mt hm thnh vin lp c s. iu ny c gi l overriding. Khi hm c cp bi tn trong lp dn xut, phin bn ca lp dn xut c chn mt cch t ng. Ton t nh phm vi c th s dng truy cp phin bn ca lp c s t lp dn xut. V d 5.2: nh ngha mt hm thnh vin lp c s trong lp dn xut v project c tn l CT5_2.PRJ File EMPLOY.H
EMPLOY.H

1: //EMPLOY.H 2: //nh ngha lp Employee 3: #ifndef EMPLOY_H 4: #define EMPLOY_H 5: 6: class Employee 7: { 8: private: 9: char *FirstName; 10: char *LastName; 11: public: 12: Employee(const char *First, const char *Last); 13: void Print() const;

203

14: ~Employee(); 15: }; 16: 17: #endif

File EMPLOY.CPP
EMPLOY.CPP

1: //EMPLOY.CPP 2: //nh ngha cc hm thnh vin ca lp Employee 3: #include <string.h> 4: #include <iostream.h> 5: #include <assert.h> 6: #include "employ.h" 7: 8: Employee::Employee(const char *First, const char *Last) 9: { 10: FirstName = new char[ strlen(First) + 1 ]; 11: assert(FirstName != 0); 12: strcpy(FirstName, First); 13: LastName = new char[ strlen(Last) + 1 ]; 14: assert(LastName != 0); 15: strcpy(LastName, Last); 16: } 17: 18: void Employee::Print() const 19: { 20: cout << FirstName << ' ' << LastName;

204

21: } 22: 23: Employee::~Employee() 24: { 25: delete [] FirstName; 26: delete [] LastName; 27: }

File HOURLY.H
HOURLY.H

1: //HOURLY.H 2: //nh ngha lp HourlyWorker 3: #ifndef HOURLY_H 4: #define HOURLY_H 5: 6: #include "employ.h" 7: 8: class HourlyWorker : public Employee 9: { 10: private: 11: float Wage; //Tin lng cho mi gi 12: float Hours; //S gi lm vic cho mt tun 13: public: 14: HourlyWorker(const char *First, const char *Last, 15: float InitHours, float InitWage);

16: float GetPay() const; //Tnh ton v tr v lng 17: void Print() const; //nh ngha li Print() ca lp c s

205

18: }; 19: 20: #endif

File HOURLY.CPP
HOURLY.CPP

1: //HOURLY.CPP 2: //nh ngha cc hm thnh vin ca lp HourlyWorker 3: #include <iostream.h> 4: #include <iomanip.h> 5: #include "hourly.h" 6: 7: HourlyWorker::HourlyWorker(const char *First, const char *Last, 8: float InitHours, float InitWage)

9: : Employee(First, Last) 10: { 11: Hours = InitHours; 12: Wage = InitWage; 13: } 14: 15: float HourlyWorker::GetPay() const 16: { 17: return Wage * Hours; 18: } 19: 20: void HourlyWorker::Print() const

206

21: { 22: cout << "HourlyWorker::Print()" << endl; 23: Employee::Print(); //Gi hm Print() ca lp c s 24: cout << " is an hourly worker with pay of" 25: 26: 27: } << " $" << setiosflags(ios::showpoint) << setprecision(2) << GetPay() << endl;

File CT5_2.CPP
CT5_2.CPP

1: //CT5_2.CPP 2: #include <iostream.h> 3: #include "hourly.h" 4: 5: int main() 6: { 7: HourlyWorker H("Bob", "Smith", 40.0, 7.50); 8: H.Print(); //Gi hm HourlyWorker::Print() 9 cout<<endl<<"Employee::Print()<<endl; 10: H.Employee::Print(); 11: return 0; 12: }

Chng ta chy v d 5.2, kt qu hnh 5.5

207

Hnh 5.5: Kt qu ca v d 5.2 V d 5.3: nh ngha mt thnh vin d liu ca lp c s trong lp dn xut.
CT5_3.CPP

1: //Chng trnh 5.3 2: #include <iostream.h> 3: class Base 4: { 5: protected: 6: int Value; 7: public: 8: Base(int X) 9: { 10: Value = X; 11: } 12: }; 13: 14: class Derived : public Base 15: { 16: private: 17: int Value; //nh ngha li thnh vin d liu 18: public: 19: Derived(int X):Base(X-1) 20: {

208

21: Value=X; 22: } 23: void Print() const 24: { 25: cout<<"Base::Value="<<Base::Value<<endl; 26: cout<<"Derived::Value="<<Value<<endl; 27: } 28: }; 29: 30: 31: int main() 32: { 33: Derived D(30); 34: D.Print(); 35: return 0; 36: }

Chng ta chy v d 5.3, kt qu hnh 5.6

Hnh 5.6: Kt qu ca v d 5.3 5.2.5 Cc lp c s public, protected v private Khi dn xut mt lp t mt lp c s, lp c s c th c k tha l public, protected v private. class <drived_class_name> : <type_of_inheritance> <base_class_name> { .. 209

}; Trong type_of_inheritance l public, protected hoc private. Mc nh l private. Khi dn xut mt lp t mt lp c s public, cc thnh vin public ca lp c s tr thnh cc thnh vin public ca lp dn xut, v cc thnh vin protected ca lp c s tr thnh cc thnh vin protected ca lp dn xut. Cc thnh vin private ca lp c s khng bao gi c truy cp trc tip t mt lp dn xut. Khi dn xut mt lp t mt lp c s protected, cc thnh vin public v protected ca lp c s tr thnh cc thnh vin protected ca lp dn xut. Khi dn xut mt lp t mt lp c s private, cc thnh vin public v protected ca lp c s tr thnh cc thnh vin private ca lp dn xut. Bng sau (hnh 5.6)tng kt kh nng truy cp cc thnh vin lp c s trong mt lp dn xut da trn thuc tnh xc nh truy cp thnh vin ca cc thnh vin trong lp c s v kiu k tha.

Kiu k tha K tha public K tha protected public trong lp dn xut. public C th truy cp trc tip bi cc hm thnh vin khng tnh, cc hm friend v cc hm khng thnh vin. K tha private protected trong lp dn private trong xut. lp dn xut. C th truy cp trc tip bi cc hm thnh vin khng tnh, cc hm friend. C th truy cp trc tip bi cc hm thnh vin khng tnh, cc hm friend.

protected trong lp dn protected trong lp dn private trong xut. xut. lp dn xut. protected C th truy cp trc tip bi cc hm thnh vin khng tnh, cc hm friend. Du trong lp dn xut. C th truy cp trc tip bi cc hm thnh vin khng tnh, cc hm friend thng qua cc hm thnh vin public v protected ca lp c s. 210 C th truy cp trc tip bi cc hm thnh vin khng tnh, cc hm friend. Du trong lp dn xut. C th truy cp trc tip bi cc hm thnh vin khng tnh, cc hm friend thng qua cc hm thnh vin public v protected ca lp c s. C th truy cp trc tip bi cc hm thnh vin khng tnh, cc hm friend. Du trong lp dn xut. C th truy cp trc tip bi cc hm thnh vin khng tnh, cc hm friend thng qua cc hm thnh vin

private

public v protected ca lp c s. Hnh 5.7: Tng kt kh nng truy cp thnh vin lp c s trong lp dn xut. 5.2.6 Cc contructor v destructor lp dn xut Bi v mt lp dn xut kt tha cc thnh vin lp c s ca n (ngoi tr constructor v destructor), khi mt i tng ca lp dn xut c khi ng, constructor lp c s phi c gi khi ng cc thnh vin lp c s ca i tng lp dn xut. Mt b khi to lp c s (s dng c php ging nh b khi to thnh vin) c th c cung cp trong constructor lp dn xut gi tng minh constructor lp c s, mt khc constructor lp dn xut s gi constructor mc nh lp c s. Cc constructor lp c s v cc ton t gn lp c s khng c k tha bi lp dn xut.Tuy nhin, cc constructor v cc ton t gn lp dn xut c th gi cc constructor v cc ton t gn lp c s. Mt constructor lp dn xut lun gi constructor lp c s ca n u tin khi to cc thnh vin lp c s ca lp dn xut. Nu constructor lp dn b b qua, constructor mc nh lp dn gi constructor lp c s. Cc destructor c gi theo th t ngc li th t gi cc constructor, v th destructor lp dn xut c gi trc destructor lp c s ca n. V d 5.4: Minh ha th t cc contructor v destructor lp c s v lp dn xut c gi v project c tn l CT5_4.PRJ File POINT.H
POINT.H

1: //POINT.H 2: //nh ngha lp Point 3: #ifndef POINT_H 4: #define POINT_H 5: 6: class Point 7: { 8: public: 9: Point(float A= 0.0, float B= 0.0); 10: ~Point();

211

11: protected: 12: float X, Y; 13: }; 14: 15: #endif

File POINT.CPP
POINT.CPP

1: //POINT.CPP 2: //nh ngha cc hm thnh vin lp Point 3: #include <iostream.h> 4: #include "point.h" 5: 6: Point::Point(float A, float B) 7: { 8: X = A; 9: Y = B; 10: cout << "Point constructor: " 11: 12: } 13: 14: Point::~Point() 15: { 16: cout << "Point destructor: " 17: 18: } << '[' << X << ", " << Y << ']' << endl; << '[' << X << ", " << Y << ']' << endl;

212

File CIRCLE.H
CIRCLE.H

1: //CIRCLE.H 2: //nh ngha lp Circle 3: #ifndef CIRCLE_H 4: #define CIRCLE_H 5: 6: #include "point.h" 7: #include <iomanip.h> 8: 9: class Circle : public Point 10: { 11: public: 12: Circle(float R = 0.0, float A = 0, float B = 0); 13: ~Circle(); 14: private: 15: float Radius; 16: }; 17: 18: #endif

File CIRCLE.CPP
CIRCLE.CPP

1: //CIRCLE.CPP 2: //nh ngha cc hm thnh vin lp Circle 3: #include "circle.h" 4:

213

5: Circle::Circle(float R, float A, float B): Point(A, B) 6: { 7: Radius = R; 8: cout << "Circle constructor: Radius is " 9: 10: } 11: 12: Circle::~Circle() 13: { 14: cout << "Circle destructor: Radius is " 15: endl; 16: } << Radius << " [" << X << ", " << Y << ']' << << Radius << " [" << A << ", " << B << ']' << endl;

File CT5_4.CPP
CT5_4.CPP

1: //CT5_4.CPP 2: //Chng trnh 5.4 3: #include <iostream.h> 4: #include "point.h" 5: #include "circle.h" 6: int main() 7: { 8: { 9: Point P(1.1, 2.2); 10: } 11: cout << endl;

214

12: Circle C1(4.5, 7.2, 2.9); 13: cout << endl; 14: Circle C2(10, 5, 5); 15: cout << endl; 16: return 0; 17: }

Chng ta chy v d 5.4, kt qu hnh 5.8

Hnh 5.8: Kt qu ca v d 5.4 5.2.7 Chuyn i ngm nh i tng lp dn xut sang i tng lp c s Mc d mt i tng lp dn xut cng l mt i tng lp c s, kiu lp dn xut v kiu lp c s th khc nhau. Cc i tng lp dn xut c th c x l nh cc i tng lp c s. iu ny c ngha bi v lp dn xut c cc thnh vin tng ng vi mi thnh vin ca lp c s. Php gn theo chiu hng ngc li l khng cho php bi v gn mt i tng lp c s cho i tng lp dn xut s cho php thm cc thnh vin lp dn xut khng xc nh. Mt con tr tr ti mt i tng lp dn xut c th c chuyn i ngm nh thnh mt con tr tr ti mt i tng lp c s bi v mt i tng lp dn xut l mt i tng lp c s. C bn cch trn v i snh cc con tr lp c s v cc con tr lp dn xut vi cc i tng lp c s v cc i tng lp dn xut: Tham chiu ti mt i tng lp c s vi mt con tr lp c s th khng phc tp. 215

Tham chiu ti mt i tng lp dn xut vi mt con tr lp dn xut th khng phc tp. Tham chiu ti i tng lp dn xut vi mt con tr lp c s th an ton bi v i tng lp dn xut cng l mt i tng lp c s ca n. Nh vy on m ch c th tham chiu ti cc thnh vin lp c s. Nu on m tham chiu ti cc thnh vin lp dn xut thng qua con tr lp c s, trnh bin dch s bo mt li v c php. Tham chiu ti mt i tng lp c s vi mt con tr lp dn xut th c li c php. u tin con tr lp dn xut phi c p sang con tr lp c s. 5.2.8 Mt s v d: Chng ta s xem xt mt phn cp cc lp Point, Circle, Cylinder nh hnh 5.9

Hnh 5.9 V d 5.5: Lp Point v project c tn l CT5_5.PRJ (gm cc file POINT.CPP, CT5_5.CPP). File POINT.H:
POINT.H

1: //POINT.H 2: //nh ngha lp Point 3: #ifndef POINT_H 4: #define POINT_H 5: 6: class Point

216

7: { 8: protected: 9: float X,Y; 10: public: 11: Point(float A = 0, float B = 0); 12: void SetPoint(float A, float B); 13: float GetX() const 14: { 15: return X; 16: } 17: float GetY() const 18: { 19: return Y; 20: } 21: friend ostream & operator <<(ostream &Output, const Point &P); 22: }; 23: 24: #endif

File POINT.CPP
POINT.CPP

1: //POINT.CPP 2: //nh ngha cc hm thnh vin ca lp Point 3: #include <iostream.h> 4: #include "point.h" 5:

217

6: Point::Point(float A, float B) 7: { 8: SetPoint(A, B); 9: } 10: 11: void Point::SetPoint(float A, float B) 12: { 13: X = A; 14: Y = B; 15: } 16: 17: ostream & operator <<(ostream &Output, const Point &P) 18: { 19: Output << '[' << P.X << ", " << P.Y << ']'; 20: return Output; 21: }

File CT5_5.CPP:
CT5_5.CPP

1: //CT5_5.CPP 2: //Chng trnh 5.5 3: #include <iostream.h> 4: #include "point.h" 5: 6: int main() 7: { 8: Point P(7.2, 11.5);

218

9: cout << "X coordinate is " << P.GetX() 10: << endl << "Y coordinate is " << P.GetY();

11: P.SetPoint(10, 10); 12: cout << endl << endl << "The new location of P is "<< P << endl; 14: return 0; 15: }

Chng ta chy v d 5.5, kt qu hnh 5.10

Hnh 5.10: Kt qu ca v d 5.5 V d 5.6: Lp Circle v project c tn l CT5_6.PRJ (gm cc file POINT.CPP, CIRCLE.CPP, CT5_6.CPP). File CIRCLE.H:
CIRCLE.H

1: //CIRCLE.H 2: //nh ngha lp Circle 3: #ifndef CIRCLE_H 4: #define CIRCLE_H 5: 6: #include "point.h" 7: 8: class Circle : public Point 9: {

219

10: protected: 11: float Radius; 12: public: 13: Circle(float R = 0.0, float A = 0, float B = 0); 14: void SetRadius(float R); 15: float GetRadius() const; 16: float Area() const; 17: friend ostream & operator <<(ostream &Output, const Circle &C); 18: }; 19: 20: #endif

File CIRCLE.CPP
CIRCLE.CPP

1: //CIRCLE.CPP 2: //nh ngha cc hm thnh vin ca lp Circle 3: #include <iostream.h> 4: #include <iomanip.h> 5: #include "circle.h" 6: 7: Circle::Circle(float R, float A, float B) : Point(A, B) 8: { 9: Radius = R; 10: } 11: 12: void Circle::SetRadius(float R)

220

13: { 14: Radius = R; 15: } 16: 17: float Circle::GetRadius() const 18: { 19: return Radius; 20: } 21: 22: float Circle::Area() const 23: { 24: return 3.14159 * Radius * Radius; 25: } 26: 27: //Xut mt Circle theo dng: Center = [X, Y]; Radius = #.## 28: ostream & operator <<(ostream &Output, const Circle &C) 29: { 30: Output << "Center = [" << C.X << ", " << C.Y 31: << "]; Radius = " << setiosflags(ios::showpoint) 32: << setprecision(2) << C.Radius; 33: return Output; 34: }

File CT5_6.CPP
CT5_6.CPP

1: //CT5_6.CPP 2: //Chng trnh 5.6

221

3: #include <iostream.h> 4: #include "point.h" 5: #include "circle.h" 6: 7: int main() 8: { 9: Circle C(2.5, 3.7, 4.3); 10: cout << "X coordinate is " << C.GetX() 11: 12: << endl << "Y coordinate is " << C.GetY() << endl << "Radius is " << C.GetRadius();

13: C.SetRadius(4.25); 14: C.SetPoint(2, 2); 15: cout << endl << endl << "The new location and radius of C are" 16: endl; << endl << C << endl << "Area " << C.Area() <<

17: Point &PRef = C; 18: cout << endl << "Circle printed as a Point is: " 19: 20: return 0; 21: } << PRef << endl;

Chng ta chy v d 5.6, kt qu hnh 5.11

222

Hnh 5.11: Kt qu ca v d 5.6 V d 5.7: Lp Cylinder v project c tn l CT5_7.PRJ (gm cc file POINT.CPP, CIRCLE.CPP, CYLINDR.CPP, CT5_7.CPP). File CYLINDR.H
CYLINDR.H

1: //CYLINDR.H 2: //nh ngha lp Cylinder 3: #ifndef CYLINDR_H 4: #define CYLINDR_H 5: 6: #include "circle.h" 7: 8: class Cylinder : public Circle 9: { 10: protected: 11: float Height; 12: public: 13: Cylinder(float H = 0.0, float R = 0.0, float A = 0.0, float B = 0.0); 14: void SetHeight(float); 15: float GetHeight() const;

223

16: float Area() const; 17: float Volume() const; 18: friend ostream & operator <<(ostream &Output, const Cylinder &C); 19: }; 20: 21: #endif

File CYLINDR.CPP
CYLINDR.CPP

1: //CYLINDR.CPP 2: //nh ngha cc hm thnh vin lp Cylinder 3: #include <iostream.h> 4: #include <iomanip.h> 5: #include "cylindr.h" 6: 7: Cylinder::Cylinder(float H, float R, float A, float B) : Circle(R, A, B) 8: { 9: Height = H; 10: } 11: 12: void Cylinder::SetHeight(float H) 13: { 14: Height = H; 15: } 16: 17: float Cylinder::GetHeight() const

224

18: { 19: return Height; 20: } 21: 22: //Tnh din tch ca Cylinder (din tch mt) 23: float Cylinder::Area() const 24: { 25: return 2*Circle::Area()+2 * 3.14159*Radius*Height; 26: } 27: 28: float Cylinder::Volume() const 29: { 30: return Circle::Area() * Height; 31: } 32: 33: ostream & operator <<(ostream &Output, const Cylinder& C) 34: { 35: Output << "Center = [" << C.X << ", " << C.Y 36: << "]; Radius = " << setiosflags(ios::showpoint) 37: << setprecision(2) << C.Radius 38: << "; Height = " << C.Height; 39: return Output; 40: }

File CT5_7.CPP
CT5_7.CPP

1: //CT5_7.CPP

225

2: //Chng trnh 5.7 3: #include <iostream.h> 4: #include <iomanip.h> 5: #include "point.h" 6: #include "circle.h" 7: #include "cylindr.h" 8: int main() 9: { 10: Cylinder Cyl(5.7, 2.5, 1.2, 2.3); 11: cout << "X coordinate is " << Cyl.GetX() << endl 12: 13: 14: ; << "Ycoordinate is " << Cyl.GetY() << endl << "Radius is " << Cyl.GetRadius() << endl << "Height is " << Cyl.GetHeight() << endl << endl

15: Cyl.SetHeight(10); 16: Cyl.SetRadius(4.25); 17: Cyl.SetPoint(2, 2); 18: cout << "The new location, radius, " 19: << "and height of Cyl are:" << endl << Cyl << endl;

20: Point &PRef = Cyl; 21: cout << endl << "Cylinder printed as a Point is: " 22: << PRef << endl << endl;

23: Circle &cRef = Cyl; 24: cout << "Cylinder printed as a Circle is:" << endl << cRef 25: 26: return 0; 27: } << endl << "Area: " << cRef.Area() << endl;

226

Chng ta chy v d 5.7, kt qu hnh 5.12

Hnh 5.12: Kt qu ca v d 5.7

5.3 A K THA (MULTIPLE INHERITANCE)


Mt lp c th c dn xut t nhiu lp c s, s dn xut nh vy c gi l a k tha. a k tha c ngha l mt lp dn xut k tha cc thnh vin ca cc lp c s khc nhau. Kh nng mnh ny khuyn khch cc dng quan trng ca vic s dng li phn mm, nhng c th sinh ra cc vn nhp nhng. V d 5.7: Lp Circle v project c tn l CT5_8.PRJ (gm cc file DIRIVED.CPP, CT5_8.CPP). File BASE1.H
BASE1.H

1: //BASE1.H 2: //nh ngha lp Base1 3: #ifndef BASE1_H 4: #define BASE1_H 5: 6: class Base1 7: { 8: protected:

227

9: int Value; 10: public: 11: Base1(int X) 12: { 13: Value = X; 14: } 15: int GetData() const 16: { 17: return Value; 18: } 19: }; 20: 21: #endif

File BASE2.H
BASE2.H

1: //BASE2.H 2: //nh ngha lp Base2 3: #ifndef BASE2_H 4: #define BASE2_H 5: 6: class Base2 7: { 8: protected: 9: char Letter; 10: public: 11: Base2(char C)

228

12: { 13: Letter = C; 14: } 15: char GetData() const 16: { 17: return Letter; 18: } 19: }; 20: 21: #endif

File DERIVED.H
DERIVED.H

1: //DERIVED.H 2: //nh ngha lp Derived m k tha t nhiu lp c s (Base1 & Base2) 3: #ifndef DERIVED_H 4: #define DERIVED_H 5: 6: #include "base1.h" 7: #include "base2.h" 8: 9: class Derived : public Base1, public Base2 10: { 11: private: 12: float Real; 13: public:

229

14: Derived(int, char, float); 15: float GetReal() const; 16: friend ostream & operator <<(ostream &Output, const Derived &D); 17: }; 18: 19: #endif

File DERIVED.CPP
DERIVED.CPP

1: //DERIVED.CPP 2: //nh ngha cc hm thnh vin ca lp Derived 3: #include <iostream.h> 4: #include "derived.h" 5: 6: Derived::Derived(int I, char C, float F) 7: : Base1(I), Base2(C) //Gi cc constructor lp c s 8: { 9: Real = F; 10: } 11: 12: float Derived::GetReal() const 13: { 14: return Real; 15: } 16: 17: ostream & operator <<(ostream &Output, const Derived &D)

230

18: { 19: Output << " Integer: " << D.Value << endl 20: << " Character: " << D.Letter << endl 21: << "Real number: " << D.Real; 22: return Output; 23: }

File CT5_8.CPP
CT5_8.CPP

1: //CT5_8.CPP 2: //Chng trnh 5.8 3: #include <iostream.h> 4: #include "base1.h" 5: #include "base2.h" 6: #include "derived.h" 7: 8: int main() 9: { 10: Base1 B1(10), *Base1Ptr; 11: Base2 B2('Z'), *Base2Ptr; 12: Derived D(7, 'A', 3.5); 13: cout << "Object B1 contains integer " 14: 15: 16: 17: endl; << B1.GetData() << endl << "Object B2 contains character " << B2.GetData() << endl << "Object D contains:" << endl << D << endl <<

231

18: cout << "Data members of Derived can be" 19: 20: 21: 22: << " accessed individually:" << endl << " Integer: " << D.Base1::GetData() << endl << " Character: " << D.Base2::GetData() << endl << "Real number: " << D.GetReal() << endl << endl;

23: cout << "Derived can be treated as an " 24: << "object of either base class:" << endl;

25: Base1Ptr = &D; 26: cout << "Base1Ptr->GetData() yields " 27: << Base1Ptr->GetData() << endl ;

28: Base2Ptr = &D; 29: cout << "Base2Ptr->GetData() yields " 30: 31: return 0; 32: } << Base2Ptr->GetData() << endl;

Chng ta chy v d 5.8, kt qu hnh 5.13

232

Hnh 5.13: Kt qu ca v d 5.8 Vic k tha nhiu lp c s to ra mt lot cc im nhp nhng trong cc chng trnh C++. Chng hn, trong cc chng trnh ca v d 5.8, nu thc hin lnh: D.GetData(); th trnh bin dch (Borland C++ 3.1) s bo li: Member is ambiguous: Base1::GetData and Base1::GetData Bi v lp Derived k tha hai hm khc nhau c cng tn l GetData() t hai lp c s ca n. Base1::GetData() l hm thnh vin public ca lp c s public, v n tr thnh mt hm thnh vin public ca Derived. Base2::GetData() l hm thnh vin public ca lp c s public, v n tr thnh mt hm thnh vin public ca Derived. Do trnh bin dch khng th xc nh hm thnh vin GetData() ca lp c s no gi thc hin. V vy, chng ta phi s dng tn lp c s v ton t nh phm vi xc nh hm thnh vin ca lp c s lc gi hm GetData(). C php ca mt lp k tha nhiu lp c s: class <drived_class_name> : <type_of_inheritance> <base_class_name1> , <type_of_inheritance> <base_class_name2>, { .. }; 233

Trnh t thc hin constructor trong a k tha: constructor lp c s xut hin trc s thc hin trc v cui cng mi ti constructor lp dn xut. i vi destructor c trnh t thc hin theo th t ngc li.

5.4 CC LP C S O (VIRTUAL BASE CLASSES)


Chng ta khng th khai bo hai ln cng mt lp trong danh sch ca cc lp c s cho mt lp dn xut. Tuy nhin vn c th c trng hp cng mt lp c s c cp nhiu hn mt ln trong cc lp t tin ca mt lp dn xut. iu ny pht sinh li v khng c cch no phn bit hai lp c s gc. V d 5.9:
CT5_9.CPP

1: //Chng trnh 5.9 2: #include <iostream.h> 3: class A 4: { 5: public: 6: int X1; 7: }; 8: 9: class B : public A 10: { 11: public: 12: float X2; 13: }; 14: 15: class C : public A 16: { 17: public: 18: double X3; 19: }; 20:

234

21: class D : public B,public C 22: { 23: public: 24: char X4; 25: }; 26: 27: int main() 28: { 29: D Obj; 30: Obj.X2=3.14159F; 31: Obj.X1=0; //Nhp nhng 32: Obj.X4='a'; 33: Obj.X3=1.5; 34: cout<<"X1="<<Obj.X1<<endl; //Nhp nhng 35: cout<<"X2="<<Obj.X2<<endl; 36: cout<<"X3="<<Obj.X3<<endl; 37: cout<<"X4="<<Obj.X4<<endl; 38: return 0; 39: }

Khi bin dch chng trnh v d 5.9, trnh bin dch s bo li dng 31 v 34: Member is ambiguous: A::X1 and A::X1

235

Hnh 5.14 y chng ta thy c hai lp c s A cho lp D, v trnh bin dch khng th no nhn bit c vic truy cp X1 c k tha thng qua B hoc truy cp X1 c k tha thng qua C. khc phc iu ny, chng ta ch nh mt cch tng minh trong lp D nh sau: Obj.C::X1=0; Tuy nhin, y cng ch l gii php c tnh chp v, bi thc cht X1 no trong trng hp no cng c. Gii php cho vn ny l khai bo A nh lp c s kiu virtual cho c B v C. Khi chng trnh v d 5.9 c vit li nh sau: V d 5.10:
CT5_10.CPP

1: //Chng trnh 5.10 2: #include <iostream.h> 3: class A 4: { 5: public: 6: int X1; 7: }; 8: 9: class B : virtual public A 10: { 11: public:

236

12: float X2; 13: }; 14: 15: class C : virtual public A 16: { 17: public: 18: double X3; 19: }; 20: 21: class D : public B,public C 22: { 23: public: 24: char X4; 25: }; 26: 27: int main() 28: { 29: D Obj; 30: Obj.X2=3.14159F; 31: Obj.X1=0; //OK 32: Obj.X4='a'; 33: Obj.X3=1.5; 34: cout<<"X1="<<Obj.X1<<endl; //OK 35: cout<<"X2="<<Obj.X2<<endl; 36: cout<<"X3="<<Obj.X3<<endl; 37: cout<<"X4="<<Obj.X4<<endl; 38: return 0;

237

39: }

Chng ta chy v d 5.10, kt qu hnh 5.15

Hnh 5.15: Kt qu ca v d 5.10 Cc lp c s kiu virtual, c cng mt kiu lp, s c kt hp to mt lp c s duy nht c kiu cho bt k lp dn xut no k tha chng. Hai lp c s A trn bt gi s tr thnh mt lp c s A duy nht cho bt k lp dn xut no t B v C. iu ny c ngha l D ch c mt c s ca lp A, v vy trnh c s nhp nhng.

6.1 DN NHP
Tnh a hnh (polymorphism) l kh nng thit k v ci t cc h thng m c th m rng d dng hn. Cc chng trnh c th c vit x l tng qut nh cc i tng lp c s cc i tng ca tt c cc lp tn ti trong mt phn cp. Kh nng cho php mt chng trnh sau khi bin dch c th c nhiu din bin xy ra l mt trong nhng th hin ca tnh a hnh tnh mun mu mun v ca chng trnh hng i tng, mt thng ip c gi i (gi n i tng) m khng cn bit i tng nhn thuc lp no. thc hin c tnh a hnh, cc nh thit k C++ cho chng ta dng c ch kt ni ng (dynamic binding) thay cho c ch kt ni tnh (static binding) ngay khi chng trnh bin dch c dng trong cc ngn ng c in nh C, Pascal,

6.2 PHNG THC O (VIRTUAL FUNCTION)


Khi xy dng cc lp ca mt chng trnh hng i tng to nn mt cu trc phn cp hoc cy ph h, ngi lp trnh phi chun b cc hnh vi giao tip chung ca cc lp . Hnh vi giao tip chung s c dng th hin cng mt hnh vi, nhng c cc hnh ng khc nhau, chnh l phng thc o. y l mt phng thc tn ti c hiu lc nhng khng c thc trong lp c s, cn trong cc lp dn xut. Nh vy phng thc o ch c xy dng khi c mt h thng cy ph h. Phng thc ny s c gi thc hin t thc th ca lp dn xut nhng m t v chng trong lp c s. Chng ta khai bo phng thc o bng thm t kha virtual pha trc. Khi cc phng thc c cng tn vi phng thc ny trong cc lp dn xut cng l phng thc o. V d 6.1:
CT6_1.CPP

1: //Chng trnh 6.1

238

2: #include <iostream.h> 3: 4: class Base 5: { 6: public: 7: virtual void Display() 8: { 9: cout<<"class Base"<<endl; 10: } 11: }; 12: 13: class Derived : public Base 14: { 15: public: 16: virtual void Display() 17: { 18: cout<<"class Derived"<<endl; 19: } 20: }; 21: 21: void Show(Base *B) 22: { 23: B->Display(); //Con tr B ch n phng thc Display() no (ca lp Base 24 //hoc lp Derived) ty vo lc chy chng trnh. 25: } 26: int main()

239

27: { 28: Base *B=new Base; 29: Derived *D=new Derived; 30: B->Display(); //Base::Display() 31: D->Display(); //Derived::Display() 32: Show(B); //Base::Display() 33: Show(D); //Derived::Display() 34: return 0; 35: }

Chng ta chy v d 6.1, kt qu hnh 6.1

Hnh 6.1: Kt qu ca v d 6.1 Trong v d 6.1, lp c s Base c phng thc Display() c khai bo l phng thc o. Phng thc ny trong lp dn xut Derived c nh ngha li nhng cng l mt phng thc o. Tht ra, khng ra khng c khai bo virtual cho phng thc Display() ca lp Derived cng chng sao, trnh bin dch vn hiu l phng thc o. Tuy nhin, khai bo virtual r rng cc lp dn xut lm cho chng trnh trong sng, d hiu hn. Hai dng 30 v 31, chng ta bit chc phng thc Display() ca lp no c gi (ca lp Base hoc lp Derived). Nhng hai dng 32 v 33, nu khng c c ch kt ni ng, chng ta on rng vic gi hm Show() s lun lun ko theo phng thc Base::Display(). Qu vy, b i khai bo virtual cho phng thc Base::Display(), khi dng lnh: Show(D); gi n Base::Display() v i tng lp dn xut cng l i tng lp c s (ngha l tdb t ng chuyn i kiu: i tng D kiu Derived chuyn thnh kiu Base. Nh khai bo virtual cho phng thc Base::Display() nn s khng thc hin gi phng thc Base::Display() mt cch cng nhc trong hm Show() m chun b mt c ch mm do cho vic gi phng thc Display() ty thuc vo s xc nh kiu ca tham s vo lc chy chng trnh. C ch ra sao? Khi nhn thy c khai bo virtual trong lp c s, trnh bin dch s thm vo mi i tng ca lp c s v cc lp dn xut ca n mt con tr ch n bng phng thc o (virtual function 240

table). Con tr c tn l vptr (virtual pointer). Bng phng thc o l ni cha cc con tr ch n on chng trnh bin dch ng vi cc phng thc o. Mi lp c mt bng phng thc o. Trnh bin dch ch lp bng phng thc o khi bt u c vic to i tng ca lp. n khi chng trnh chy, phng thc o ca i tng mi c ni kt v thi hnh thng qua con tr vptr. Trong v d 6.1, lnh gi hm: Show(D); i tng D thuc lp Derived tuy b chuyn i kiu thnh mt i tng thuc lp Base nhng n khng hon ton ging mt i tng ca Base chnh cng nh B. Nu nh con tr vptr trong B ch n v tr trn bng phng thc o ng vi phng thc Base::Display(), th con tr vptr trong D vn cn ch n phng thc Derived::Display() cho d D b chuyn kiu thnh Base. l l do ti sao lnh: Show(D); gi n phng thc Derived::Display(). Cc c trng ca phng thc o: Phng thc o khng th l cc hm thnh vin tnh. Mt phng thc o c th c khai bo l friend trong mt lp khc nhng cc hm friend ca lp th khng th l phng thc o. Khng cn thit phi ghi r t kha virtual khi nh ngha mt phng thc o trong lp dn xut ( cng chng nh hng g). s kt ni ng c thc hin thch hp cho tng lp dc theo cy ph h, mt khi phng thc no c xc nh l o, t lp c s n cc lp dn xut u phi nh ngha thng nht v tn, kiu tr v v danh sch cc tham s. Nu i vi phng thc o lp dn xut, chng ta li s sut nh ngha cc tham s khc i mt cht th trnh bin dch s xem l phng thc khc. y chnh l iu kin kt ni ng. V d 6.2:
CT6_2.CPP

1: //Chng trnh 6.2 2: #include <iostream.h> 3: 4: class Base 5: { 6: public:

241

7: virtual void Print(int A,int B); 8: }; 9: 10: class Derived : public Base 11: { 12: public: 13: virtual void Print(int A,double D); 14: }; 15: 16: void Base::Print(int A,int B) 17: { 18: cout<<"A="<<A<<",B="<<B<<endl; 19: } 20: 21: void Derived::Print(int A,double D) 22: { 23: cout<<"A="<<A<<",D="<<D<<endl; 24: } 25: 26: void Show(Base *B) 27: { 28: B->Print(3,5); 29: } 30: 31: int main() 32: { 33: Base *B=new Base;

242

34: Derived *D=new Derived; 35: Show(B); //Base::Print() 36: Show(D); //Base::Print() 37: return 0; 38: }

Chng ta chy v d 6.2, kt qu hnh 6.2

Hnh 6.2: Kt qu ca v d 6.2 Trong v d 6.2, trong lp c s Base v lp dn xut Derived u c phng thc o Print(). Nhng quan st k chng ta, phng thc Print() trong lp Derived c tham s th hai khc kiu vi phng thc Print() trong lp Base. V th, chng ta khng th ch i lnh dng 36 s gi n phng thc Derived::Print(int,double). Phng thc Derived::Print(int,double) nm ngoi ng dy phng thc o nn hm Show() ch lun gi n phng thc Derived::Print(int,int) m thi. Do c khai bo virtual i vi phng thc Derived::Print(int,double), chng ta c th ni phng thc ny s m u cho mt ng dy phng thc o Print(int,double) mi nu sau lp Derived cn c cc lp dn xut ca n.

6.3 LP TRU TNG (ABSTRACT CLASS)


Trong qu trnh thit k chng trnh theo hng i tng, to nn mt h thng ph h mang tnh k tha cao, ngi lp trnh phi on trc s pht trin ca cu trc, t chn la nhng thnh vin ph hp cho cc lp trn cng. R rng y l mt cng vic v cng kh khn. trnh tnh trng ngi lp trnh xy dng cc i tng lng ph b nh, ngn ng C++ cho php chng ta thit k cc lp c cc khng phng thc o khng lm g c, v cng khng th to ra i tng thuc lp . Nhng lp nh vy gi l lp tru tng. Trong cu trc trn hnh 6.3, khng phi lp no cng thc s cn n phng thc Print(), nhng n c mt khp ni to ra b mt chung cho mi lp trong cu trc cy. Phng thc ca lp trn cng nh A::Print() thng l phng thc o c c tnh a hnh.

243

Hnh 6.3 Nh , vi hm sau: void Show(A* a) { a->Print(); } chng ta c th truyn i tng kiu cho n (A, B, C, D hoc E) m vn gi n ng phung thc Print() ph hp d kiu ca i tng lc bin dch vn cn cha bit. Vi vai tr "lt ng" nh vy, phng thc A::Print() c th chng c ni dung g c class A { public: virtual void Print() { } }; Khi ngi ta gi phng thc A::Print() l phng thc o rng (null virtual function), n chng lm g ht. Tuy nhin lp A vn l mt lp bnh thng, chng ta c th to ra mt i tng thuc n, c th truy cp ti phng thc A::Print(). trnh trnh trng v tnh to ra i tng thuc lp ny, ngi ta thng 244

xy dng lp tru tng, trnh bin dch cho php to ra lp c cc phng thc thun o (pure virtual function) nh sau: class A { public: virtual void Print() = 0; }; Phng thc o Print() by gi l phng thc thun o phng thc c tn c gn bi gi tr zero. Lp A cha phng thc thun o c gi l lp tru tng. V d 6.3:
CT6_3.CPP

1: //Chng trnh 6.3 2: #include <iostream.h> 3: 4: class A 5: { 6: public: 7: virtual void Print()=0; //Phng thc thun o 8: }; 9: 10: class B : public A 11: { 12: public: 13: virtual void Print() 14: { 15: cout<<"Class B"<<endl; 16: } 17: };

245

18: 19: class C : public B 20: { 21: public: 22: virtual void Print() 23: { 24: cout<<"Class C"<<endl; 25: } 26: }; 27: 28: void Show(A *a) 29: { 30: a->Print(); 31: } 32: 33: int main() 34: { 35: B *b=new B; 36: C *c=new C; 37: Show(b); //B::Print() 38: Show(c); //C::Print() 39: return 0; 40: }

Chng ta chy v d 6.3, kt qu hnh 6.4

246

Hnh 6.4: Kt qu ca v d 6.3 Lp A c to ra lm c s cho vic hnh thnh cc lp con chu (B v C). Nh c Phng thc o Print() t lp A cho ti lp C, tnh a hnh c th hin. Lu : Chng ta khng th to ra mt i tng ca lp tru tng, nhng hon ton c th to ra mt con tr tr n lp ny (v con tr khng phi l i tng thuc lp) hoc l mt tham chiu. Nu trong lp k tha t lp tru tng chng ta khng nh ngha phng thc thun o, do tnh k tha n s bao hm phng thc thun o ca lp c s, nn lp dn xut ny s tr thnh lp tru tng. Theo nh ngha lp tru tng, nu trong lp dn xut (t lp c s tru tng) chng ta nh ngha thm mt phng thc thun o khc, lp ny cng s tr thnh lp tru tng.

6.4 CC THNH VIN O CA MT LP


6.4.1 Ton t o Ton t thc cht cng l mt hm nn chng ta c th to ra cc ton t o trong mt lp. Tuy nhin do a nng ha khi to mt ton t cn ch n cc kiu ca cc ton hng phi s dng kiu ca lp c s gc c ton t o. V d 6.4: a nng ha ton t vi hm ton t l phng thc o.
CT6_4.CPP

1: //Chng trnh 6.4: Ton t o 2: #include <iostream.h> 3: 4: class A 5: { 6: protected: 7: int X1; 8: public: 9: A(int I)

247

10: { 11: X1=I; 12: } 13: virtual A& operator + (A& T); 14: virtual A& operator = (A& T); 15: virtual int GetA() 16: { 17: return X1; 18: } 19: virtual int GetB() 20: { 21: return 0; 22: } 23: virtual int GetC() 24: { 25: return 0; 26: } 27: void Print(char *St) 28: { 29: cout<<St<<":X1="<<X1<<endl; 30: } 31: }; 32: 33: class B : public A 34: { 35: protected: 36: int X2;

248

37: public: 38: B(int I,int J):A(I) 39: { 40: X2=J; 41: } 42: virtual A& operator + (A& T); 43: virtual A& operator = (A& T); 44: virtual int GetB() 45: { 46: return X2; 47: } 48: void Print(char *St) 49: { 50: cout<<St<<":X1="<<X1<<",X2="<<X2<<endl; 51: } 52: }; 53: 54: class C : public B 55: { 56: protected: 57: int X3; 58: public: 59: C(int I,int J,int K):B(I,J) 60: { 61: X3=K; 62: } 63: virtual A& operator + (A& T);

249

64: virtual A& operator = (A& T); 65: virtual int GetC() 66: { 67: return X3; 68: } 69: void Print(char *St) 70: { 71: cout<<St<<":X1="<<X1<<",X2="<<X2<<",X3="<<X3<<endl; 72: } 73: }; 74: 75: A& A::operator + (A& T) 76: { 77: X1+=T.GetA(); 78: return *this; 79: } 80: 81: A& A::operator = (A& T) 82: { 83: X1=T.GetA(); 84: return *this; 85: } 86: 87: A& B::operator + (A& T) 88: { 89: X1+=T.GetA(); 90: X2+=T.GetB();

250

91: return *this; 92: } 93: 94: A& B::operator = (A& T) 95: { 96: X1=T.GetA(); 97: X2=T.GetB(); 98: return *this; 99: } 100: 101:A& C::operator + (A& T) 102: { 103: X1+=T.GetA(); 104: X2+=T.GetB(); 105: X3+=T.GetC(); 106: return *this; 107 } 108: 109: A& C::operator = (A& T) 110: { 111: X1=T.GetA(); 112: X2=T.GetB(); 113: X3=T.GetC(); 114: return *this; 115: } 116: 117: void AddObject(A& T1,A& T2)

251

118: { 119: T1=T1+T2; 120: } 121: 122: int main() 123: { 124: A a(10); 125: B b(10,20); 126: C c(10,20,30); 127: a.Print("a"); 128: b.Print("b"); 129: c.Print("c"); 130: AddObject(a,b); 131: a.Print("a"); 132: AddObject(b,c); 133: b.Print("b"); 134: AddObject(c,a); 135: c.Print("c"); 136: a=b+c; 137: a.Print("a"); 138: c=c+a; 139: c.Print("c"); 140: return 0; 141: }

Chng ta chy v d 6.4, kt qu hnh 6.5

252

Hnh 6.5: Kt qu ca v d 6.4 6.4.2 C constructor v destructor o hay khng?: Khi mt i tng thuc lp c phng thc o, thc hin c ch kt ni ng, trnh bin dch s to thm mt con tr vptr nh mt thnh vin ca lp, con tr ny c nhim v qun l a ch ca phng thc o. Mt lp ch c mt bng phng thc o, trong khi c th c nhiu i tng thuc lp, nn khi mt i tng khc thuc cng lp to ra th con tr vptr cn ti. Chnh v vy bng phng thc o phi c to ra trc khi gi thc hin constructor, nn constructor khng th l phng thc o. Ngc li do mt lp ch c mt bng phng thc o nn khi mt i tng thuc lp b hy b, bng phng thc o vn cn , v con tr vptr vn cn . Hn na, destructor c gi thc hin trc khi vng nh dnh cho i tng b thu hi, do destructor c th l phng thc o. Tuy nhin, constructor ca mt lp c th gi phng thc o khc. iu ny hon ton khng c g mu thun vi c ch kt ni ng. V d 6.5:
CT6_5.CPP

1: //Chng trnh 6.5: Destructor o 2: #include <iostream.h> 3: 4: class Base 5: { 6: public: 7: virtual ~Base() 8: { 9: cout<<"~Base"<<endl; 10: } 11: };

253

12: 13: class Derived:public Base 14: { 15: public: 16: virtual ~Derived() 17: { 18: cout<<"~Derived"<<endl; 18: } 19: }; 20: 21: int main() 22: { 23: Base *B; 24: B = new Derived; 25: delete B; 26: return 0; 27: }

Chng ta chy v d 6.5, kt qu hnh 6.6

Hnh 6.6: Kt qu ca v d 6.5 Nu destructor khng l phng thc o th khi gii phng i tng B ch c destructor ca lp c s c gi m thi nhng khi destructor l phng thc o th khi gii phng i tng B ( dng 25) destructor ca lp dn xut c gi thc hin ri n destructor ca lp c s.

6.5 MT S V D
254

: Chng ta s dng cc phng thc o v tnh a hnh thc hin bng lng da trn loi ngi lao ng. Chng ta s dng lp c s Employ. Cc lp dn xut ca Employ l Boss m ngi c tr tin lng hng tun c nh bt chp s gi lm vic, CommissionWorker m ngi c tin lng c s cng thm phn trm ca hng bn, PieceWorker m ngi c tr bi s cc mc sn xut, v HourlyWorker m ngi c tr bi theo gi v nhn ngoi gi. V d 6.6: File EMPLOY.H
EMPLOY.H

1: //EMPLOY.H 2: //Lp c s tru tng Employee 3: #ifndef EMPLOY_H 4: #define EMPLOY_H 5: class Employee 6: { 7: private: 8: char *FirstName; 9: char *LastName; 10: public: 11: Employee(const char *First, const char *Last); 12: ~Employee(); 13: const char *GetFirstName() const; 14: const char *GetLastName() const; 15: virtual float Earnings() const = 0; 16: virtual void Print() const = 0; 17: }; 18: 19: #endif

File EMPLOY.CPP 255

256

EMPLOY.CPP

1: //EMPLOY.CPP 2: //nh ngha hm thnh vin ca lp c s tru tng 3: #include <iostream.h> 4: #include <string.h> 5: #include <assert.h> 6: #include "employ.h" 7: 8: Employee::Employee(const char *First, const char *Last) 9: { 10: FirstName = new char[ strlen(First) + 1 ]; 11: assert(FirstName != 0); 12: strcpy(FirstName, First); 13: LastName = new char[ strlen(Last) + 1 ]; 14: assert(LastName != 0); 15: strcpy(LastName, Last); 16: } 17: 18: Employee::~Employee() 19: { 20: delete [] FirstName; 21: delete [] LastName; 22: } 23: 24: const char *Employee::GetFirstName() const 25: { 26: return FirstName; //Ni gi phi xa vng nh 27: }

257

28: 29: const char *Employee::GetLastName() const 30: { 31: return LastName; //Ni gi phi xa vng nh 32: }

File BOSS.H
BOSS.H

1: //BOSS.H 2: //Lp Boss dn xut t Employee 3: #ifndef BOSS_H 4: #define BOSS_H 5: #include "employ.h" 6: 7: class Boss : public Employee 8: { 9: private: 10: float WeeklySalary; 11: public: 12: Boss(const char * First, const char *Last, float S = 0.0); 13: void SetWeeklySalary(float S); 14: virtual float Earnings() const; 15: virtual void Print() const; 16: }; 17: 18: #endif

258

File BOSS.CPP
BOSS.CPP

1: //BOSS.CPP 2: //nh ngha hm thnh vin ca lp Boss 3: #include <iostream.h> 4: #include "boss.h" 5: 6: Boss::Boss(const char *First, const char *Last, float S) : Employee(First, Last) 7: { 8: WeeklySalary = S > 0 ? S : 0; 9: } 10: 11: void Boss::SetWeeklySalary(float S) 12: { 13: WeeklySalary = S > 0 ? S : 0; 14: } 15: 16: float Boss::Earnings() const 17: { 18: return WeeklySalary; 19: } 20: 21: void Boss::Print() const 22: { 23: cout << endl << " Boss: " << GetFirstName() 24: 25: } << ' ' << GetLastName();

259

File COMMIS.H
COMMIS.H

1: //COMMIS.H 2: //Lp CommissionWorker dn xut t Employee 3: #ifndef COMMIS_H 4: #define COMMIS_H 5: #include "employ.h" 6: 7: class CommissionWorker : public Employee 8: { 9: private: 10: float Salary; ; //Lng c bn mi tun 11: float Commission; //Khi lng cc mc c bn 12: unsigned Quantity; //Tng cc mc bn mi tun 13: public: 14: CommissionWorker(const char *First, const char *Last, 15: float S = 0.0, float C = 0.0, unsigned Q = 0); 16: void SetSalary(float S); 17: void SetCommission(float C); 18: void SetQuantity(unsigned Q); 19: virtual float Earnings() const; 20: virtual void Print() const; 21: }; 22: 23: #endif

File COMMIS.CPP

260

COMMIS.CPP

1: //COMMIS.CPP 2: //nh ngha hm thnh vin ca lp CommissionWorker 3: #include <iostream.h> 4: #include "commis.h" 5: 6: CommissionWorker::CommissionWorker(const char *First,const char *Last, 7: float S, float C, unsigned Q) 8: : Employee(First, Last) 9: { 10: Salary = S > 0 ? S : 0; 11: Commission = C > 0 ? C : 0; 12: Quantity = Q > 0 ? Q : 0; 13: } 14: 15: void CommissionWorker::SetSalary(float S) 16: { 17: Salary = S > 0 ? S : 0; 18: } 19: 20: void CommissionWorker::SetCommission(float C) 21: { 22: Commission = C > 0 ? C : 0; 23: } 24: 25: void CommissionWorker::SetQuantity(unsigned Q) 26: {

261

27: Quantity = Q > 0 ? Q : 0; 28: } 29: 30: float CommissionWorker::Earnings() const 31: { 32: return Salary + Commission * Quantity; 33: } 34: 35: void CommissionWorker::Print() const 36: { 37: cout << endl << "Commission worker: " << GetFirstName() 38: 39: } << ' ' << GetLastName();

File HOURLY.H
HOURLY.H

1: //HOURLY.H 2: //nh ngha lp HourlyWorker 3: #ifndef HOURLY_H 4: #define HOURLY_H 5: #include "employ.h" 6: 7: class HourlyWorker : public Employee 8: { 9: private: 10: float Wage; //Tin lng mi gi 11: float Hours; //S gi lm vic mi tun

262

12: public: 13: HourlyWorker(const char *First, const char * Last, 14: #9; #9; #9; float = 0.0, float = 0.0);

15: void SetWage(float W); 16: void SetHours(float H); 17: virtual float Earnings() const; 18: virtual void Print() const; 19: }; 20: 21: #endif

File HOURLY.CPP
HOURLY.CPP

1: //HOURLY.CPP 2: //nh ngha hm thnh vin ca lp HourlyWorker 3: #include <iostream.h> 4: #include "hourly.h" 5: 6: HourlyWorker::HourlyWorker(const char *First, const char *Last, 7: float W, float H)

8: : Employee(First, Last) 9: { 10: Wage = W > 0 ? W : 0; 11: Hours = H >= 0 && H < 168 ? H : 0; 12: } 13:

263

14: void HourlyWorker::SetWage(float W) 15: { 16: Wage = W > 0 ? W : 0; 17: } 18: 19: void HourlyWorker::SetHours(float H) 20: { 21: Hours = H >= 0 && H < 168 ? H : 0; 22: } 23: 24: float HourlyWorker::Earnings() const 25: { 26: return Wage * Hours; 27: } 28: 29: void HourlyWorker::Print() const 30: { 31: cout << endl << " Hourly worker: " << GetFirstName() 32: 33: } << ' ' << GetLastName();

File PIECE.H
PIECE.H

1: //PIECE.H 2: //Lp PieceWorker dn xut t Employee 3: #ifndef PIECE_H 4: #define PIECE_H

264

5: #include "employ.h" 6: 7: class PieceWorker : public Employee 8: { 9: private: 10: float WagePerPiece; //Lng cho mi mnh 11: unsigned Quantity; //u ra mi tun 12: public: 13: PieceWorker(const char *First, const char * Last, float W=0.0, 14: unsigned Q=0);

15: void SetWage(float W); 16: void SetQuantity(unsigned Q); 17: virtual float Earnings() const; 18: virtual void Print() const; 19: }; 20: 21: #endif

File PIECE.CPP
PIECE.CPP

1: //PIECE.CPP 2: //nh ngha hm thnh vin ca lp PieceWorker 3: #include <iostream.h> 4: #include "piece.h" 5: 7: PieceWorker::PieceWorker(const char *First, const char *Last,

265

8:

float W, unsigned Q)

9: : Employee(First, Last) 10: { 11: WagePerPiece = W > 0 ? W : 0; 12: Quantity = Q > 0 ? Q : 0; 13: } 14: 15: void PieceWorker::SetWage(float W) 16: { 17: WagePerPiece = W > 0 ? W : 0; 18: } 19: 20: void PieceWorker::SetQuantity(unsigned Q) 21: { 22: Quantity = Q > 0 ? Q : 0; 23 } 24: 25: float PieceWorker::Earnings() const 26: { 27: return Quantity * WagePerPiece; 28: } 29: 30: void PieceWorker::Print() const 31: { 32: cout << endl << " Piece worker: " << GetFirstName() 33: 34: } << ' ' << GetLastName();

266

File CT6_6.CPP
CT6_6.CPP

1: //CT6_6.CPP 2: //Chng trnh 6.6 3: #include <iostream.h> 4: #include <iomanip.h> 5: #include "employ.h" 6: #include "boss.h" 7: #include "commis.h" 8: #include "piece.h" 9: #include "hourly.h" 10: 11: int main() 12: { 13: //n nh dng xut 14: cout << setiosflags(ios::showpoint) << setprecision(2); 15: Employee *Ptr; 16: Boss B("John", "Smith", 800.00); 17: Ptr = &B; 18: Ptr->Print(); 19: cout << " earned $" << Ptr->Earnings(); 20: B.Print(); 21: cout << " earned $" << B.Earnings(); 22: CommissionWorker C("Sue", "Jones", 200.0, 3.0, 150); 23: Ptr = &C; 24: Ptr->Print();

267

25: cout << " earned $" << Ptr->Earnings(); 26: C.Print(); 27: cout << " earned $" << C.Earnings(); 28: PieceWorker P("Bob", "Lewis", 2.5, 200); 29: Ptr = &P; 30: Ptr->Print(); 31: cout << " earned $" << Ptr->Earnings(); 32: P.Print(); 33: cout << " earned $" << P.Earnings(); 34: HourlyWorker H("Karen", "Price", 13.75, 40); 35: Ptr = &H; 36: Ptr->Print(); 37: cout << " earned $" << Ptr->Earnings(); 38: H.Print(); 39: cout << " earned $" << H.Earnings(); 40: cout << endl; 41: return 0; 42: }

Chng ta chy v d 6.6, kt qu hnh 6.7

268

Hnh 6.7: Kt qu ca v d 6.6 V d 6.7: Vit li chng trnh v d 5.6 vi lp c s tru tng Shape. File SHAPE.H
SHAPE.H

1: //SHAPE.H 2: //nh ngha lp c s tru tng Shape 3: #ifndef SHAPE_H 4: #define SHAPE_H 5: 6: class Shape 7: { 8: public: 9: virtual float Area() const 10: { 11: return 0.0; 12: } 13: virtual float Volume() const 14: { 15: return 0.0; 16: } 17: virtual void PrintShapeName() const = 0; 18: virtual void Print() const = 0; 19: }; 20: 21: #endif

File POINT.H 269

270

POINT.H

1: //POINT.H 2: //nh ngha lp Point 3: #ifndef POINT_H 4: #define POINT_H 5: #include <iostream.h> 6: #include "shape.h" 7: 8: class Point : public Shape 9: { 10: private: 11: float X, Y; 12: public: 13: Point(float A = 0, float B = 0); 14: void SetPoint(float A, float B); 15: float GetX() const 16: { 17: return X; 18: } 19: float GetY() const 20: { 21: return Y; 22: } 23: virtual void PrintShapeName() const 24: { 25: cout << "Point: "; 26: } 27: virtual void Print() const;

271

28: friend ostream &operator <<(ostream &Ouput, const Point &P); 29: }; 30: 31: #endif

File POINT.CPP
POINT.CPP

1: //POINT.CPP 2: //nh ngha hm thnh vin cho lp Point 3: #include <iostream.h> 4: #include "point.h" 5: 6: Point::Point(float A, float B) 7: { 8: SetPoint(A, B); 9: } 10: 11: void Point::SetPoint(float A, float B) 12: { 13: X = A; 14: Y = B; 15: } 16: 17: void Point::Print() const 18: { 19: cout << '[' << X << ", " << Y << ']'; 20: }

272

21: 22: ostream &operator<<(ostream &Output, const Point &P) 23: { 24: P.Print(); 25: return Output; 26: }

File CIRCLE.H
A.CPP

1: //CIRCLE.H 2: //nh ngha lp Circle 3: #ifndef CIRCLE_H 4: #define CIRCLE_H 5: #include "point.h" 6: 7: class Circle : public Point 8: { 9: private: 10: float Radius; 11: public: 12: Circle(float R = 0.0, float A = 0.0, float B = 0.0); 13: void SetRadius(float R); 14: float GetRadius() const; 15: virtual float Area() const; 16: virtual void PrintShapeName() const 17: { 18: cout << "Circle: ";

273

19: } 20: virtual void Print() const; 21: friend ostream &operator<<(ostream &Output, const Circle &C); 22: }; 23: 24: #endif

File CIRCLE.CPP:
A.CPP

1: //CIRCLE.CPP 2: //nh ngha hm thnh vin cho lp Circle 3: #include <iostream.h> 4: #include <iomanip.h> 5: #include "circle.h" 6: 7: Circle::Circle(float R, float A, float B): Point(A, B) 8: { 9: Radius = R > 0 ? R : 0; 10: } 11: 12: void Circle::SetRadius(float R) 13: { 14: Radius = R > 0 ? R : 0; 15: } 16: 17: float Circle::GetRadius() const 18: {

274

19: return Radius; 20: } 21: 22: float Circle::Area() const 23: { 24: return 3.14159 * Radius * Radius; 25: } 26: 27: void Circle::Print() const 28: { 29: cout << '[' << GetX() << ", " << GetY() 30: 31: 32: } 33: 34: ostream &operator<<(ostream &Output, const Circle &C) 35: { 36: C.Print(); 37: return Output; 38: } << "]; Radius=" << setiosflags(ios::showpoint) << setprecision(2) << Radius;

File CYLINDR.H
CYLINDR.H

1: //CYLINDR.H 2: //nh ngha lp Cylinder 3: #ifndef CYLINDR_H 4: #define CYLINDR_H

275

5: #include "circle.h" 6: 7: class Cylinder : public Circle 8: { 9: private: 10: float Height; 11: public: 12: Cylinder(float H = 0.0, float R = 0.0,float A = 0.0, float B = 0.0); 13: void setHeight(float); 14: virtual float Area() const; 15: virtual float Volume() const; 16: virtual void PrintShapeName() const 17: { 18: cout << "Cylinder: "; 19: } 20: virtual void Print() const; 21: friend ostream &operator<<(ostream &Output, const Cylinder &C); 22: }; 23: 24: #endif

File CYLINDR.CPP
CYLINDR.CPP

1: //CYLINDR.CPP 2: //nh ngha hm thnh vin cho lp Cylinder 3: #include <iostream.h>

276

4: #include <iomanip.h> 5: #include "cylindr.h" 6: 7: Cylinder::Cylinder(float H, float R, float A, float B):Circle(R, A, B) 8: { 9: Height = H > 0 ? H : 0; 10: } 11: 12: void Cylinder::setHeight(float H) 13: { 14: Height = H > 0 ? H : 0; 15: } 16: 17: float Cylinder::Area() const 18: { 19: return 2 * Circle::Area() + 2 * 3.14159 * Circle::GetRadius() * Height; 20: } 21: 22: float Cylinder::Volume() const 23: { 24: return Circle::Area() * Height; 25: } 26: 27: void Cylinder::Print() const 28: { 29: cout << '[' << GetX() << ", " << GetY()

277

30: 31: 32: 33: } 34:

<< "]; Radius=" << setiosflags(ios::showpoint) << setprecision(2) << GetRadius() << "; Height=" << Height;

35: ostream &operator <<(ostream &Output, const Cylinder& C) 36: { 37: C.Print(); 38: return Output; 39: }

File CT6_7.CPP
CT6_7.CPP

1: //CT6_7.CPP 2: //Chng trnh 6.7 3: #include <iostream.h> 4: #include <iomanip.h> 5: #include "shape.h" 6: #include "point.h" 7: #include "circle.h" 8: #include "cylindr.h" 9: 10: int main() 11: { 12: Point P(7, 11); 13: Circle C(3.5, 22, 8); 14: Cylinder Cy(10, 3.3, 10, 10);

278

15: P.PrintShapeName(); 16: cout << P << endl; 17: C.PrintShapeName(); 18: cout << C << endl; 19: Cy.PrintShapeName(); 20: cout << Cy << "\n\n"; 21: cout << setiosflags(ios::showpoint) << setprecision(2); 22: Shape *ArrayOfShapes[3]; 23: ArrayOfShapes[0] = &P; 24: ArrayOfShapes[1] = &C; 25: ArrayOfShapes[2] = &Cy; 26: for (int i = 0; i < 3; i++) 27: { 28: ArrayOfShapes[i]->PrintShapeName(); 29: cout << endl; 30: ArrayOfShapes[i]->Print(); 31: cout << "\nArea = " << ArrayOfShapes[i]->Area() 32: 33: 34: } 35: return 0; 36: } << "\nVolume = " << ArrayOfShapes[i]->Volume() << endl << endl;

Chng ta chy v d 6.7, kt qu hnh 6.8

279

Hnh 6.8: Kt qu ca v d 6.7

7.1 DN NHP
Trong chng ny, chng ta tm hiu mt t v cch thit k chng trnh theo hng i tng, cc bc c bn cn thit khi bt tay vo vit chng trnh trn quan im thit k v tho chng.

7.2 CC GIAI ON PHT TRIN H THNG


C nm giai on pht trin h thng phn mm theo hng i tng: Phn tch yu cu (Requirement analysis) Phn tch (Analysis) Thit k (Design) Lp trnh (Programming) Kim tra (Testing)

Phn tch yu cu Bng vic tm hiu cc trng hp s dng (use case) nm bt cc yu cu ca khch hng, ca vn cn gii quyt. Qua trng hp s dng ny, cc nhn t bn ngoi c tham gia vo h thng cng c m hnh ha bng cc tc nhn. Mi trng hp s dng c m t bng vn bn, c t yu cu ca khch hng. 280

Phn tch T cc c t yu cu trn, h thng s bc u c m hnh ha bi cc khi nim lp, i tng v cc c ch din t hot ng ca h thng. Trong giai on phn tch chng ta ch m t cc lp trong lnh vc ca vn cn gii quyt ch chng ta khng i su vo cc chi tit k thut.

Thit k Trong giai on thit k, cc kt qu ca qu trnh phn tch c m rng thnh mt gii php k thut. Mt s cc lp c thm vo cung cp c s h tng k thut nh lp giao din, lp c s d liu, lp chc nng,

Lp trnh y cn gi l bc xy dng, giai on ny s c t chi tit kt qu ca giai on thit k. Cc lp ca bc thit k s c chuyn thnh m ngun theo mt ngn ng lp trnh theo hng i tng no .

Kim tra Trong giai on kim tra, c bn hnh thc kim tra h thng: Kim tra tng n th (unit testing) c dng kim tra cc lp hoc cc nhm n. Kim tra tnh tch hp (integration testing), c kt hp vi cc thnh phn v cc lp kim tra xem chng hot ng vi nhau c ng khng. Kim tra h thng (system testing) ch kim tra xem h thng c p ng c chc nng m ngi dng yu cu khng. Kim tra tnh chp nhn c(acceptance testing), vic kim tra ny c thc hin bi khch hng, vic kim tra cng thc hin ging nh kim tra h thng.

7.3 CCH TM LP
Lp nn c tm t phm vi bi ton cn gii quyt, v vy tn ca lp cng nn t tn cc i tng thc m chng ta biu din. tm ra lp cho bi ton, chng ta cn tr li cc cu hi sau: C thng tin no cn lu tr hay phn tch khng? Nu c bt k thng tin no cn phi lu tr, bin i, phn tch hoc x l th chnh l mt lp d nh cn xy dng. C h thng bn ngoi bn ngoi hay khng? H thng ngoi c th c xem nh cc lp m h thng ca chng ta cha hoc tng tc vi n. C cc mu thit k, th vin lp, thnh phn, hay khng? Cc thnh phn ny c xy dng t cc project trc , t cc ng nghip hoc cc nh sn xut?

281

C thit b no m h thng phi p ng? Bt c thit b no c ni vi h thng c th chuyn thnh lp d tuyn. Tc nhn ng vai tr nh th no trong h thng? Cc vai din ny nn c xem l lp nh ngi s dng, khch hang, ngi iu khin h thng,

7.4 CC BC CN THIT THIT K CHNG TRNH


thit k mt chng trnh theo hng i tng, chng ta phi tri qua bn bc sau, t chng ta xy dng c mt cy ph h mang tnh k tha v cc mi quan h gia cc i tng: Xc nh cc dng i tng (lp) ca bi ton (nh dang cc i tng). Tm kim cc c tnh chung (d liu chung) trong cc dng i tng ny, nhng g chng cng nhau chia x. Xc nh c lp c s da trn c s cc c tnh chung ca cc dng i tng. T lp c s, s dng quan h tng qut ha c t trong vic a ra cc lp dn xut cha cc thnh phn, nhng c tnh khng chung cn li ca dng i tng. Bn cnh , chng ta cn a ra cc lp c quan h vi cc lp c s v lp dn xut; cc quan h ny c th l quan h kt hp, quan h tp hp li, quan h ph thuc. Vi cc bc trn chng ta c c cy ph h v quan h gia cc lp. i vi h thng phc tp hn, chng ta cn phi phn tch gii quyt c vn t ra theo trt t sau: Phn tch mt cch cn thn v cc i tng ca bi ton theo trt t t di ln (bottom up). Tm ra nhng g tn ti chung gia cc i tng, nhm cc c tnh ny li c cc lp c s nh hnh 7.1

Hnh 7.1 Tip tc theo hng t di ln, chng ta thit k c cc i tng ph hp nh hnh 7.2

282

Hnh 7.2 Bng cch ny, chng ta tip tc tm cc c tnh chung cho n tt cng ca cc i tng. Sau ci t theo hng i tng t trn xung bng cch ci t lp c s chung nht. Tip tc ci t cc lp dn xut trn c s cc c tnh chung ca tng nhm i tng. Cho n khi tt c cc dng i tng ca h thng c ci t xong c cy ph h.

7.5 CC V D
V d 7.1: Tnh tin lng ca cc nhn vin trong c quan theo cc dng khc nhau. Dng ngi lao ng lnh lng t ngn sch Nh nc c gi l cn b, cng chc (dng bin ch). Dng ngi lao ng lnh lng t ngn sch ca c quan c gi l ngi lm hp ng. Nh vy h thng chng ta c hai i tng: bin ch v hp ng. Hai loi i tng ny c c tnh chung l vin chc lm vic cho c quan. T y c th to nn lp c s qun l mt vin chc (lp Nguoi) bao gm m s, h tn v lng. Sau chng ta xy dng cc lp cn li k tha t lp c s trn: Lp dnh cho cn b, cng chc (lp BienChe) gm cc thuc tnh: h s lng, tin ph cp chc v. Lp dnh cho ngi lm hp ng (lp HopDong) gm cc thuc tnh: tin cng lao ng, s ngy lm vic trong thng, h s vt gi.

283

Hnh 7.3 File PERSON.H


PERSON.H

1: //PERSON.H 2: nh ngha lp Nguoi 3: #ifndef PERSON_H 4: #define PERSON_H 5: 6: #include <iostream.h> 7: 8: #define MAX_TEN 50 9: #define MAX_MASO 5 10: #define MUC_CO_BAN 120000 11: 12: class Nguoi 13: { 14: protected:

284

15: char HoTen[MAX_TEN]; 16: char MaSo[MAX_MASO]; 17: float Luong; 18: public: 19: Nguoi(); 20: virtual void TinhLuong()=0; 21: void Xuat() const; 22: virtual void Nhap(); 23: }; 24: 25: #endif

File PERSON.CPP
PERSON.CPP

1: //PERSON.CPP 2: nh ngha hm thnh vin cho lp Nguoi 3: #include <iomanip.h> 4: #include <string.h> 5: #include "person.h" 6: 7: Nguoi::Nguoi() 8: { 9: strcpy(HoTen,""); 10: strcpy(MaSo,""); 11: Luong=0; 12: } 13:

285

14: void Nguoi::Xuat() const 15: { 16: cout<<"Ma so:"<<MaSo<<",Ho va ten:"<<HoTen 17: #9; <<",Luong:"<<setiosflags(ios::fixed)<<setprecision(0)<<Luong<<endl; 18: } 19: 20: void Nguoi::Nhap() 21: { 22: cout<<"Ma so:"; 23: cin>>MaSo; 24: cin.ignore(); 25: cout<<"Ho va ten:"; 26: cin.getline(HoTen,MAX_TEN); 27: }

File STAFF.H
STAEF.H

1: //STAFF.H 2 nh ngha lp BienChe 3: #ifndef STAFF_H 4: #define STAFF_H 5: 5: #include "person.h" 6: 7: class BienChe: public Nguoi 8: {

286

9: protected: 10: float HeSoLuong; 11: float HeSoPhuCap; 12: public: 13: BienChe(); 14: virtual void TinhLuong(); 15: virtual void Nhap(); 16: }; 17: 18: #endif

File STAFF.CPP
STAEF.CPP

1: //STAFF.CPP 2: nh ngha hm thnh vin cho lp BienChe 3: #include "staff.h" 4: 5: BienChe::BienChe() 6: { 7: HeSoLuong=HeSoPhuCap=0; 8: } 9: 10: void BienChe::Nhap() 11: { 12: Nguoi::Nhap(); 13: cout<<"He so luong:"; 14: cin>>HeSoLuong;

287

15: cout<<"He so phu cap chu vu:"; 16: cin>>HeSoPhuCap; 17: } 18: 19: void BienChe::TinhLuong() 20: { 21: Luong=MUC_CO_BAN*(1.0+HeSoLuong+HeSoPhuCap); 22: }

File CONTRACT.H
CONTRACT.H

1: //CONTRACT.H 2: nh ngha lp HopDong 3: #ifndef CONTRACT_H 4: #define CONTRACT_H 5: 6: #include "person.h" 7: 8: class HopDong : public Nguoi 9: { 10: protected: 11: float TienCong; 12: float NgayCong; 13: float HeSoVuotGio; 14: public: 15: HopDong(); 16: virtual void TinhLuong();

288

17: virtual void Nhap(); 18: }; 19: 20: #endif

File CONTRACT.CPP:
CONTRACT.CPP

1: //CONTRACT.CPP 2: nh ngha hm thnh vin cho lp HopDong 3: #include "contract.h" 4: 5: HopDong::HopDong() 6: { 7: TienCong=NgayCong=HeSoVuotGio=0; 8: } 9: 10: void HopDong::Nhap() 11: { 12: Nguoi::Nhap(); 13: cout<<"Tien cong:"; 14: cin>>TienCong; 15: cout<<"Ngay cong:"; 16: cin>>NgayCong; 17: cout<<"He so vuot gio:"; 18: cin>>HeSoVuotGio; 19: } 20:

289

21: void HopDong::TinhLuong() 22: { 23: Luong=TienCong*NgayCong*(1+HeSoVuotGio); 24: }

File CT7_1.CPP:
CT7_1.CPP

1: //CT7_1.CPP 2: //Chng trnh 7.1 3: #include <iostream.h> 4: #include <ctype.h> 5: #include "person.h" 6: #include "staff.h" 7: #include "contract.h" 8: 9: int main() 10: { 11: Nguoi *Ng[100]; 12: int N=0; 13: char Chon,Loai; 14: do 15: { 16: cout<<"Bien che hay Hop dong (B/H)? "; 17: cin>>Loai; 18: Loai=toupper(Loai); 19: if (Loai=='B') 20: Ng[N]=new BienChe;

290

21: else 22: Ng[N]=new HopDong; 23: Ng[N++]->Nhap(); 24: cout<<"Tiep tuc (C/K)? "; 25: cin>>Chon; 26: Chon=toupper(Chon); 27: if ((N==100)||(Chon=='K')) 28: break; 29: } 30: while (1); 31: for(int I=0;I<N;++I) 32: { 33: Ng[I]->TinhLuong(); 34: Ng[I]->Xuat(); 35: } 36: return 0; 37: }

Chng ta chy v d 7.1, kt qu hnh 7.4

291

Hnh 7.4: Kt qu ca v d 7.1 V d 7.2: Gi s cui nm hc cn trao gii thng cho cc sinh vin xut sc v cc ging vin c nhiu cng trnh khoa hc c cng b trn tp ch. Cc lp trong cy ph h nh hnh 7.5: lp Nguoi qun l h s c nhn, lp SinhVien qun l v sinh vin v lp GiangVien qun l ging vin. Lp Nguoi: D liu h v tn. Phng thc kim tra kh nng c khen thng. y l phng thc thun o. Phng thc xut. y l phng thc thun o. Lp SinhVien: D liu im trung bnh. Phng thc kim tra kh nng c khen thng. Phng thc xut. Lp GiangVien: D liu im trung bnh. Phng thc kim tra kh nng c khen thng. Phng thc xut. 292

Hnh 7.5 File PERSON.H


PERSON.H

1: //PERSON.H 2: nh ngha lp Nguoi 3: #ifndef PERSON_H 4: #define PERSON_H 5: 6: #include <iostream.h> 7: 8: #define MAX_TEN 50 9: 10: class Nguoi 11: { 12: protected: 13: char HoTen[MAX_TEN]; 14: public:

293

15: Nguoi(char *HT); 16: virtual int DuocKhenThuong() const=0; 17: virtual void Xuat() const=0; 18: }; 19: 20: #endif

File PERSON.CPP:
PERSON.CPP

1: //PERSON.CPP 2: nh ngha hm thnh vin cho lp Nguoi 3: #include <string.h> 4: #include "person.h" 5: 6: Nguoi::Nguoi(char *HT) 7: { 8: strcpy(HoTen,HT); 9: }

File STUDENT.H:
STUDENT.H

1: //STUDENT.H 2: nh ngha lp SinhVien 3: #ifndef STUDENT_H 4: #define STUDENT_H 5:

294

6: #include "person.h" 7: 8: class SinhVien : public Nguoi 9: { 10: protected: 11: float DiemTB; 12: public: 13: SinhVien(char *HT,float DTB); 14: virtual int DuocKhenThuong() const; 15: virtual void Xuat() const; 16: }; 17: 18: #endif

File STUDENT.CPP:
STUDENT.CPP

1: //STUDENT.CPP 2: nh ngha hm thnh vin cho lp SinhVien 3: #include "student.h" 4: 5: SinhVien::SinhVien(char *HT,float DTB):Nguoi(HT) 6: { 7: DiemTB=DTB; 8: } 9: 10: int SinhVien::DuocKhenThuong() const 11: {

295

12: return DiemTB>9.0; 13: } 14: 15: void SinhVien::Xuat() const 16: { 17: cout<<"Ho va ten cua sinh vien:"<<HoTen; 18: }

File TEACHER.H:
TEACHER.H

1: //TEACHER.H 2: nh ngha lp GiangVien 3: #ifndef TEACHER_H 4: #define TEACHER_H 5: 6: #include "person.h" 7: 8: class GiangVien : public Nguoi 9: { 10: protected: 11: int SoBaiBao; 12: public: 13: GiangVien(char *HT,int SBB); 14: virtual int DuocKhenThuong() const; 15: virtual void Xuat() const; 16: }; 17:

296

18: #endif

File TEACHER.CPP:
TEACHER.CPP

1: //TEACHER.CPP 2: nh ngha hm thnh vin cho lp GiangVien 3: #include "teacher.h" 4: 5: GiangVien::GiangVien(char *HT,int SBB):Nguoi(HT) 6: { 7: SoBaiBao=SBB; 8: } 9: 10: int GiangVien::DuocKhenThuong() const 11: { 12: return SoBaiBao>5; 13: } 14: 15: void GiangVien::Xuat() const 16: { 17: cout<<"Ho va ten cua giang vien:"<<HoTen; 18: }

File CT7_2.CPP:
CT7_2.CPP

1: //CT7_2.CPP

297

2: //Chng trnh 7.2 3: #include <ctype.h> 4: #include "person.h" 5: #include "student.h" 6: #include "teacher.h" 7: 8: int main() 9: { 10: Nguoi *Ng[100]; 11: int N=0; 12: char Chon,Loai; 13: char HoTen[MAX_TEN]; 14: do 15: { 16: cout<<"Ho va ten:"; 17: cin.getline(HoTen,MAX_TEN); 18: cout<<"Sinh vien hay Giang vien(S/G)? "; 19: cin>>Loai; 20: Loai=toupper(Loai); 21: if (Loai=='S') 22: { 23: float DTB; 24: cout<<"Diem trung binh:"; 25: cin>>DTB; 26: Ng[N++]=new SinhVien(HoTen,DTB); 27: } 28: else

298

29: { 30: int SoBaiBao; 31: cout<<"So bai bao:"; 32: cin>>SoBaiBao; 33: Ng[N++]=new GiangVien(HoTen,SoBaiBao); 34: } 35: cout<<"Tiep tuc (C/K)? "; 36: cin>>Chon; 37: Chon=toupper(Chon); 38: cin.ignore(); 39: if ((N==100)||(Chon=='K')) 40: break; 41: } 42: while (1); 43: for(int I=0;I<N;++I) 44: { 45: Ng[I]->Xuat(); 46: if (Ng[I]->DuocKhenThuong()) 47: cout<<". Nguoi nay duoc khen thuong"; 48: cout<<endl; 49: } 50: return 0; 51: }

Chng ta chy v d 7.2, kt qu hnh 7.6

299

Hnh 7.6: Kt qu ca v d 7.2 V d 7.3: Gi s cn phi to cc hnh: hnh trn v hnh ch nht c t theo hai mu red v blue. Xy dng mt cy ph h qun l cc hnh ny. Trc ht chng ta cn c lp c s Shape lu tr thng tin chung cho cc hnh, sau l hai lp dn xut Rectangle v hnh hnh ch nht v Circle v hnh trn nh hnh 7.7 Lp Shape: Ta tm. Mu ng bin. Mu t. Phng thc thit lp t mu. Phng thc v hnh. y l phng thc thun o. Lp Rectangle: Chiu di v chiu rng. Phng thc v hnh. 300

Lp Circle: Bn knh. Phng thc v hnh.

Hnh 7.7 File SHAPE.H:


SHAPE.H

1: //SHAPE.H 2: nh ngha lp Shape 3: #ifndef SHAPE_H 4: #define SHAPE_H 5: 6: #include <iostream.h> 7: #include <graphics.h> 8: 9: class Shape 10: {

301

11: protected: 12: int XC,YC; //Ta tm 13: int BoundaryColor; //Mu ng bin 14: int FillColor; //Mu t 15: void Setting() const; //Thit lp cc thng s v v t mu 16: public: 17: Shape(int X,int Y,int BC,int FC); 18: virtual void Draw() const=0; 19: }; 20: 21: #endif

File SHAPE.CPP:
SHAPE.CPP

1: //SHAPE.CPP 2: nh ngha hm thnh vin cho lp Shape 3: #include "shape.h" 4: 5: Shape::Shape(int X,int Y,int BC,int FC) 6: { 7: XC=X; 8: YC=Y; 9: BoundaryColor=BC; 10: FillColor=FC; 11: } 12: 13: void Shape::Setting() const

302

14: { 15: setcolor(BoundaryColor); 16: setlinestyle(SOLID_LINE,0,THICK_WIDTH); 17: setfillstyle(SOLID_FILL,FillColor); 18: }

File RECT.H:
RECT.H

1: //Rect.H 2: nh ngha lp Rectangle 3: #ifndef RECT_H 4: #define RECT_H 5: 6: #include "shape.h" 7: 8: class Rectangle : public Shape 9: { 10: protected: 11: int Width,Height; 12: public: 13: Rectangle(int X,int Y,int BC,int FC,int W,int H); 14: virtual void Draw() const; 15: }; 16: 17: #endif

File RECT.CPP:

303

RECT.CPP

1: //RECT.CPP 2: nh ngha hm thnh vin cho lp Rectangle 3: #include "rect.h" 4: 5: Rectangle::Rectangle(int X,int Y,int BC,int FC,int W,int H): Shape(X,Y,BC,FC) 6: { 7: Width=W; 8: Height=H; 9: } 10: 11: void Rectangle::Draw() const 12: { 13: Setting(); 14: rectangle(XC-Width/2,YC-Height/2,XC+Width/2,YC+Height/2); 15: floodfill(XC,YC,BoundaryColor); 16: }

File CIRCLE.H:
CIRCLE.H

1: //CIRCLE.H 2: nh ngha lp Circle 3: #ifndef CIRCLE_H 4: #define CIRCLE_H 5: 6: #include "shape.h" 7:

304

8: class Circle : public Shape 9: { 10: protected: 11: int Radius; 12: public: 13: Circle(int X,int Y,int BC,int FC,int R); 14: virtual void Draw() const; 15: }; 16: 17: #endif

File CIRCLE.CPP:
CIRCLE.CPP

1: //CIRCLE.CPP 2: nh ngha hm thnh vin cho lp Circle 3: #include "circle.h" 4: 5: Circle::Circle(int X,int Y,int BC,int FC,int R):Shape(X,Y,BC,FC) 6: { 7: Radius=R; 8: } 9: 10: void Circle::Draw() const 11: { 12: Setting(); 13: circle(XC,YC,Radius);

305

14: floodfill(XC,YC,BoundaryColor); 15: }

File CT7_3.CPP:
CT7_3.CPP

1: //CT7_3.CPP 2: //Chng trnh 7.3 3: #include <conio.h> 4: #include <stdlib.h> 5: #include "shape.h" 6: #include "rect.h" 7: #include "circle.h" 8: 9: int main() 10: { 11: int GDriver = DETECT, GMode, ErrorCode; 12: ErrorCode = registerbgidriver(EGAVGA_driver); 13: if (ErrorCode < 0) 14: { 15: cout<<"Graphics error:"<<grapherrormsg(ErrorCode)<<endl; 16: cout<<"Press any key to halt:"; 17: getch(); 18: exit(1); 19: } 20: initgraph(&GDriver, &GMode, ""); 21: ErrorCode = graphresult(); 22: if (ErrorCode != grOk)

306

23: { 24: cout<<"Graphics error:"<<grapherrormsg(ErrorCode)<<endl; 25: cout<<"Press any key to halt:"; 26: getch(); 27: exit(1); 28: } 29: Shape* S[2]; 30: Rectangle R(100,100,WHITE,BLUE,100,50); 31: Circle C(200,250,WHITE,RED,80); 32: S[0]=&R; 33: S[1]=&C; 34: for(int I=0;I<2;++I) 35: S[I]->Draw(); 36: getch(); 37: closegraph(); 38: return 0; 39: }

Chng ta chy v d 7.3, kt qu hnh 7.8

307

Hnh 7.8: Kt qu ca v d 7.3

8.1 DN NHP
Cc th vin chun C++ cung cp mt tp hp cc kh nng nhp/xut rng ln. Trong chng ny chng ta tm hiu mt phm vi ca cc kh nng phn ln cc thao tc nhp xut. Phn ln cc c tnh nhp xut m t y theo hng i tng. Kiu ny ca nhp/xut thi hnh vic s dng cc c tnh khc ca C++ nh cc tham chiu, a nng ha hm v a nng ha ton t. Nh chng ta s thy, C++ s dng nhp/xut kiu an ton (type safe). Mi thao tc nhp/xut c thc hin mt cch t ng theo li nhy cm v kiu d liu. Mi thao tc nhp xut c c nh ngha thch hp x l mt kiu d liu c th th hm c gi x l kiu d liu . Nu khng c i snh gia kiu ca d liu hin ti v mt hm cho vic x l kiu d liu , mt ch dn li bin dch c thit lp. V th d liu khng thch hp khng th "lch" qua h thng. Cc ngi dng c th ch nh nhp/xut ca cc kiu d liu do ngi dng nh ngha cng nh cc kiu d liu chun. Tnh m rng ny l mt trong cc c tnh quan trng ca C++.

8.2 CC DNG(STREAMS)
Nhp/xut C++ xy ra trong cc dng ca cc byte. Mt dng n gin l mt dy tun t cc byte. Trong cc thao tc nhp, cc byte chy t thit b (chng hn: mt bn phm, mt a, mt kt ni mng) ti b nh chnh. Trong cc thao tc xut, cc byte chy t b nh chnh ti mt thit b (chng hn: mt mn hnh, mt my in, mt a, mt kt ni mng). ng dng lin kt vi cc byte. Cc byte c th biu din cc k t ASCII, bn trong nh dng d liu th, cc nh ha, ting ni s, hnh nh s hoc bt c loi thng tin mt ng dng c th i hi. Cng vic ca cc c ch h thng nhp/xut l di chuyn cc byte t cc thit b ti b nh v ngc li theo li chc v ng tin cy. Nh th cc di chuyn thng bao gm s di chuyn c hc nh s quay ca mt a hoc mt bng t, hoc nhn phm ti mt bn phm. Thi gian cc di chuyn ny 308

thng thng khng l so vi thi gian b x l thao tc d liu ni ti. V th, cc thao tc nhp/xut i hi c k hoch cn thn v iu chnh bo m s thi hnh ti a. C++ cung cp c hai kh nng nhp/xut "mc thp" (low-level) v "mc cao" (high-level). Cc kh nng nhp/xut mc thp (ngha l nhp/xut khng nh dng) ch nh c th s byte no phi c di chuyn hon ton t thit b ti b nh hoc t b nh ti thit b. Trong cc di chuyn nh th, byte ring r l mc cn quan tm. V th cc kh nng mc thp cung cp tc cao, cc di chuyn dung lng cao, nhng cc kh nng ny khng phi l tin li lm cho lp trnh vin. Cc lp trnh vin u thch quan im nhp/xut mc cao, ngha l nhp/xut c nh dng, trong cc byte c nhm thnh cc n v c ngha nh cc s nguyn, cc s chm ng, cc k t, cc chui v cc kiu do ngi dng nh ngha. 8.2.1 Cc file header ca th vin iostream: Th vin iostream ca C++ cung cp hng trm kh nng ca nhp/xut. Mt vi tp tin header cha cc phn ca giao din th vin. Phn ln chng trnh C++ thng include tp tin header <iostream.h> m cha cc thng tin c bn i hi tt c cc thao tc dng nhp/xut. Tp tin header <iostream.h> cha cc i tng cin, cout, cerr v clog m tng ng vi dng nhp chun, dng xut chun, dng li chun khng vng m v dng li chun vng m. C hai kh nng nhp/xut nh dng v khng nh dng c cung cp. Header <iomanip.h> cha thng tin hu ch cho vic thc hin nhp/xut nh dng vi tn gi l cc b x l dng biu hin bng tham s (parameterized stream manipulators). Header <fstream.h> cha cc thng tin quan trng cho cc thao tc x l file do ngi dng kim sot. Header <strstream.h> cha cc thng tin quan trng cho vic thc hin cc nh dng trong b nh. iu ny tng t x l file, nhng cc thao tc nhp/xut ti v t mng cc k t hn l file. Header <stdiostream.h> cha cc thng tin quan trng cho cc chng trnh trn cc kiu nhp/xut ca C v C++. Cc chng trnh mi phi trnh kiu nhp/xut C, nhng cn th hiu chnh cc chng trnh C, hoc tin trin chng trnh C thnh C++. 8.2.2 Cc lp v cc i tng ca dng nhp/xut: Th vin iostream cha nhiu lp x l mt s a dng rng ca cc thao tc nhp/xut. Lp istream h tr cc thao tc dng nhp. Lp ostream h tr cc thao tc dng xut. Lp iostream h tr c hai thao tc dng nhp v dng xut. Lp istream v lp ostream u k tha n t lp c s ios. Lp iostream c k tha thng qua a k tha t hai lp istream v ostream.

309

Hnh 8.1: Mt phn ca phn cp lp dng nhp/xut a nng ha ton t cung cp mt k hiu thch hp cho vic thc hin nhp/xut. Ton t dch chuyn tri (<<) c a nng ha nh r dng xut v c tham chiu nh l ton t chn dng. Ton t dch chuyn phi (>>) c a nng ha nh r dng nhp v c tham chiu nh l ton t trch dng. Cc ton t ny c s dng vi cc i tng dng chun cin, cout, cerr v clog, v bnh thng vi cc i tng dng do ngi dng nh ngha. cin l mt i tng ca lp istream v c ni l "b rng buc ti" (hoc kt ni ti) thit b nhp chun, thng thng l bn phm. Ton t trch dng c s dng lnh sau to ra mt gi tr cho bin nguyn X c nhp t cin ti b nh: int X; cin >> X; cout l mt i tng ca lp ostream v c ni l "b rng buc ti" thit b xut chun, thng thng l mn hnh. Ton t chn dng c s dng lnh sau to ra mt gi tr cho bin nguyn X c xut t b nh ti thit b chun: cout << X; cerr l mt i tng ca lp ostream v c ni l "b rng buc ti" thit b li chun. Vic xut i tng cerr l khng vng m. iu ny c ngha l mi ln chn ti cerr to ra kt xut ca n xut hin ngay tc th; iu ny thch hp cho vic thng bo nhanh chng ngi dng khi c s c. clog l mt i tng ca lp ostream v c ni l "b rng buc ti" thit b li chun. Vic xut i tng cerr l c vng m. iu ny c ngha l mi ln chn ti cerr to ra kt xut ca n c gi trong vng m cho n khi vng m y hoc vng m c flush. Vic x l file ca C++ s dng cc lp ifstream thc hin cc thao tc nhp file, ofstream cho cc thao tc xut file, v fstream cho cc thao tc nhp/xut file. Lp ifstream k tha t istream, ofstream lp k tha t ostream, v lp fstream k tha t iostream.

310

Hnh 8.2: Mt phn ca phn cp lp dng nhp/xut vi vic x l file.

8.3 DNG XUT


ostream ca C++ cung cp kh nng thc hin xut nh dng v khng nh dng. Cc kh nng xut bao gm: xut cc kiu d liu chun vi ton t chn dng; xut cc k t vi hm thnh vin put(); xut khng nh dng vi hm thnh vin write; xut cc s nguyn dng thp phn, bt phn v thp lc phn; xut cc gi tr chm ng vi chnh xc khc nhau, vi du chm thp phn, theo k hiu khoa hc v theo k hiu c nh; xut d liu theo cc trng n thm cc k t ch nh; v xut cc mu t ch hoa theo k hiu khoa hc v k hiu thp lc phn. 8.3.1 Ton t chn dng: Dng xut c th c thc hin vi ton t chn dng, ngha l ton t << a nng ha. Ton t << c a nng ha xut cc mc d liu ca cc kiu c sn, xut chui, v xut cc gi tr con tr. V d 8.1: Minh ha xut chui s dng mt lnh chn dng.
CT8_1.CPP

1: //Chng trnh 8.1:Xut mt chui s dng chn dng 2: #include <iostream.h> 3: 4: int main() 5: { 6: cout<<"Welcome to C++!\n";

311

7: return 0; 8: }

Chng ta chy v d 8.1, kt qu hnh 8.3

Hnh 8.3: Kt qu ca v d 8.1 V d 8.2: Minh ha xut chui s dng nhiu lnh chn dng.
CT8_2.CPP

1: //Chng trnh 8.2:Xut mt chui s dng hai chn dng 2: #include <iostream.h> 3: 4: int main() 5: { 6: cout<<"Welcome to"; 7: cout<<"C++!\n"; 8: return 0; 9: }

Chng ta chy v d 8.2, kt qu hnh 8.4

Hnh 8.4: Kt qu ca v d 8.2 Hiu qu ca chui thot \n (newline) cng t c bi b x l dng (stream manipulator) endl (end line). V d 8.3: 312

CT8_3.CPP

1: //Chng trnh 8.3:S dng b x l dng endl 2: #include <iostream.h> 3: 4: int main() 5: { 6: cout<<"Welcome to"; 7: cout<<"C++!"; 8: cout<<endl; 9: return 0; 10: }

Chng ta chy v d 8.3, kt qu hnh 8.5

Hnh 8.5: Kt qu ca v d 8.3 B x l dng endl a ra mt k t newline, v hn na, flush vng m xut (ngha l to ra vng m xut c xut ngay lp tc k c n cha y). Vng m xut cng c th c flush bng: cout<<flush; V d 8.4: Cc biu thc c th xut
CT8_4.CPP

1: //Chng trnh 8.4: Xut gi tr biu thc. 2: #include <iostream.h> 3: 4: int main() 5: { 6: cout<<"47 plus 53 is ";

313

7: cout<< (47+53); 8: cout<<endl; 9: return 0; 10: }

Chng ta chy v d 8.4, kt qu hnh 8.6

Hnh 8.6: Kt qu ca v d 8.4 8.3.2 Ni cc ton t chn dng v trch dng: Cc ton t a nng ha << v >> c th c theo dng ni vo nhau. V d 8.5: Ni cc ton t a nng ha
CT8_5.CPP

1: //Chng trnh 8.5: Ni ton t << a nng ha. 2: #include <iostream.h> 3: 4: int main() 5: { 6: cout<<"47 plus 53 is "<< (47+53)<<endl; 7: return 0; 8: }

Chng ta chy v d 8.5, kt qu hnh 8.7

314

Hnh 8.7: Kt qu ca v d 8.5 Nhiu chn dng dng 6 trong v d 8.5 c thc thi nu c th vit: (((cout<<"47 plus 53 is ")<< (47+53))<<endl); ngha l << lin kt t tri qua phi. Loi lin kt ca cc ton t chn dng c php bi v ton t a nng ha << tr v mt tham chiu ti i tng ton hng bn tri ca n, ngha l cout. V th biu thc t trong ngoc bn cc tri: (cout<<"47 plus 53 is ") xut ra mt chui ch nh v tr v mt tham chiu ti cout. iu ny cho php biu thc t trong ngoc gia c c lng: (cout<< (47+53)) xut gi tr nguyn 100 v tr v mt tham chiu ti cout. Sau biu thc t trong ngoc bn cc phi c c lng: cout<<endl; xut mt newline, flush cout v tr v mt tham chiu ti cout. Tr v cui cng ny khng c s dng. 8.3.3 Xut cc bin kiu char *: Trong nhp/xut kiu C, tht cn thit cho lp trnh vin cung cp thng tin kiu. C++ xc nh cc kiu d liu mt cch t ng mt ci tin hay hn C. i khi iu ny l mt tr ngi. Chng hn, chng ta bit rng mt chui k t l kiu char *. Mc ch ca chng ta in gi tr ca con tr , ngha l a ch b nh ca k t u tin ca chui . Nhng ton t << c a nng ha in d liu ca kiu char * nh l chui kt thc k t null. Gii php l p con tr thnh kiu void *. V d 8.6: In a ch lu trong mt bin kiu char *
CT8_6.CPP

1: //Chng trnh 8.6 2: #include <iostream.h> 3: 4: int main() 5: { 6: char *Str = "test"; 7: cout << "Value of Str is: " << Str

315

8: 9:

<< "\nValue of (void *)Str is: " << (void *)Str << endl;

10: return 0; 11: }

Chng ta chy v d 8.6, kt qu hnh 8.8

Hnh 8.8: Kt qu ca v d 8.6 8.3.4 Xut k t vi hm thnh vin put(); Ni vi nhau hm put(): Hm thnh vin put() ca lp ostream xut mt k t c dng : ostream& put(char ch); Chng hn: cout.put(A); Gi put() c th c ni vo nhau nh: cout.put(A).put(\n); Hm put() cng c th gi vi mt biu thc c gi tr l m ASCII nh: cout.put(65);

8.4 DNG NHP


Dng nhp c th c thc hin vi ton t trch, ngha l ton t a nng ha >>. Bnh thng ton t ny b qua cc k t khong trng (nh cc blank, tab v newline). trong dng nhp. Ton t trch dng tr v zero (false) khi kt thc file (end-of-file) c bt gp trn mt dng; Ngc li, ton t trch dng tr v mt tham chiu ti i tng xuyn qua n c ko theo. Mi dng cha mt tp cc bit trng thi (state bit) s dng iu khin trng thi ca dng (ngha l nh dng, n nh cc trng thi li,). Trch dng sinh ra failbit ca dng c thit lp nu d liu ca kiu sai c nhp, v sinh ra badbit ca dng c thit lp nu thao tc sai. 8.4.1 Ton t trch dng: c hai s nguyn s dng i tng cin v ton t trch dng a nng ha >>. 316

V d 8.7:
CT8_7.CPP

1: //Chng trnh 8.7 2: #include <iostream.h> 3: 4: int main() 5: { 6: int X, Y; 7: cout << "Enter two integers: "; 8: cin >> X >> Y; 9: cout << "Sum of " << X << " and " << Y << " is: " 10: << (X + Y) << endl;

11: return 0; 12: }

Chng ta chy v d 8.7, kt qu hnh 8.9

Hnh 8.9: Kt qu ca v d 8.7 Mt cch ph bin nhp mt dy cc gi tr l s dng ton t trch dng trong vng lp while. Ton t trch dng tr v false (0) khi end-of-file c bt gp: V d 8.8:
CT8_8.CPP

1: //Chng trnh 8.8 2: #include <iostream.h> 3: 4: int main()

317

5: { 6: int Grade, HighestGrade = -1; 7: cout << "Enter grade (enter end-of-file to end): "; 8: while (cin >> Grade) 9: { 10: if (Grade > HighestGrade ) 11: HighestGrade = Grade; 12: cout << "Enter grade (enter end-of-file to end): "; 13: } 14: cout << endl << "Highest grade is: " << HighestGrade<< endl; 15: return 0; 16: }

Chng ta chy v d 8.8, kt qu hnh 8.10

Hnh 8.10: Kt qu ca v d 8.8 8.4.2 Cc hm thnh vin get() v getline(): Hm istream::get() c cc dng sau: (1) int get(); (2) istream& get(unsigned char &ch); (3) istream& get(signed char &ch); 318

(4) istream& get(unsigned char * puch, int len, char delim=\n); (5) istream& get(signed char * psch, int len, char delim=\n); Dng (1) trch k t n t dng v tr v n hoc EOF khi end-of-file trn dng c bt gp. Dng (2) v (3) trch mt k t n t dng v lu tr n vo ch. Dng (4) v (5) trch cc k t t dng cho n khi hoc delim c tm thy, gii hn len t n, hoc end-of-file c bt gp. Cc k t c lu trong con tr ch n mng k t puch hoc psch. V d 8.9: S dng hm get() dng (1)
CT8_9.CPP

1: //Chng trnh 8.9 2: #include <iostream.h> 3: int main() 4: { 5: int Ch; 6: cout << "Before input, cin.eof() is " << cin.eof() << endl 7: endl; << "Enter a sentence followed by end-of-file:" <<

8: while ( ( Ch = cin.get() ) != EOF) 9: cout.put(Ch); 10: cout << endl << "EOF in this system is: " << Ch << endl; 11: cout << "After input, cin.eof() is " << cin.eof() << endl; 12: return 0; 13: }

Chng ta chy v d 8.9, kt qu hnh 8.11

319

Hnh 8.11: Kt qu ca v d 8.9 Trong v d 8.9 trn, chng ta c s dng hm ios::eof() c dng sau: int eof(); Hm tr v gi tri khc zero nu end-of-file bt gp. V d 8.10: S dng hm get() dng (5)
ACT8_10.CPP

1: //Chng trnh 8.10 2: #include <iostream.h> 3: 4: const int SIZE = 80; 5: 6: int main() 7: { 8: char Buffer1[SIZE], Buffer2[SIZE]; 9: cout << "Enter a sentence:" << endl; 10: cin >> Buffer1; 11: cout << endl << "The string read with cin was:" << endl 12: << Buffer1 << endl << endl;

13: cin.get(Buffer2, SIZE); 14: cout << "The string read with cin.get was:" << endl 15: 16: return 0; 17: } << Buffer2 << endl;

320

Chng ta chy v d 8.10, kt qu hnh 8.12

Hnh 8.12: Kt qu ca v d 8.10 Hm istream::getline() c cc dng sau: (1) istream& getline(unsigned char * puch, int len, char delim=\n); (2) istream& getline(signed char * psch, int len, char delim=\n); V d 8.11: S dng hm getline()
CT8_11.CPP

1: //Chng trnh 8.11 2: #include <iostream.h> 3: 4: const SIZE = 80; 5: 6: int main() 7: { 8: char Buffer[SIZE]; 9: cout << "Enter a sentence:" << endl; 10: cin.getline(Buffer, SIZE); 11: cout << endl << "The sentence entered is:" << endl 12: << Buffer << endl;

321

13: return 0; 14: }

Chng ta chy v d 8.11, kt qu hnh 8.13

Hnh 8.13: Kt qu ca v d 8.11 8.4.3 Cc hm thnh vin khc ca istream: Hm ignore(): istream& ignore(int nCount = 1, int delim = EOF); Trch v loi b ln n nCount k t. Vic trch dng nu delim c bt gp hoc nu endof-file bt gp. Hm putback(): istream& putback(char ch); t mt k t ngc li dng nhp. Hm peek(): int peek(); Hm tr v k t k tip m khng trch n t dng. 8.4.4 Nhp/xut kiu an ton: C++ cung cp nhp/xut kiu an ton (type-safe). Cc ton t << v >> c a nng ha nhn cc mc d liu ca kiu c th. Nu d liu bt ng c x l, cc c hiu li khc nhau c thit lp m ngi dng c th kim tra xc nh nu mt thao tc nhp/xut thnh cng hoc tht bi. Phn sau chng ta s kho st k hn.

8.5 NHP/ XUT KHNG NH DNG VI READ(),GCOUNT() V WRITE()


Nhp/xut khng nh dng c thc hin vi cc hm thnh vin istream::read() v ostream::write(). 322

Hm istream::read(): istream& read(unsigned char* puch, int nCount); istream& read(signed char* psch, int nCount); Trch cc byte t dng cho n khi gii hn nCount t n hoc cho n khi end- of-file t n. Hm ny c ch cho dng nhp nh phn. Hm ostream::write(): ostream& write(const unsigned char* puch, int nCount); ostream& write(const signed char* psch, int nCount); Chn nCount byte vo t vng m (c tr bi puch v psch) vo dng. Nu file c m ch text, cc k t CR c th c chn vo. Hm ny c ch cho dng xut nh phn. Chng hn: char Buff[]="HAPPY BIRTHDAY"; cout.write(Buff,10); Hm istream::gcount(): int gcount(); Hm tr v s k t trch bi hm nhp khng nh dng cui cng. V d 8.12: S dng hm getline()
CT8_12.CPP

1: //Chng trnh 8.12 2: #include <iostream.h> 3: 4: const int SIZE = 80; 5: 6: int main() 7: { 8: char Buffer[SIZE]; 9: cout << "Enter a sentence:" << endl; 10: cin.read(Buffer, 20);

323

11: cout << endl << "The sentence entered was:" << endl; 12: cout.write(Buffer, cin.gcount()); 13: cout << endl; 14: return 0; 15: }

Chng ta chy v d 8.12, kt qu hnh 8.14

Hnh 8.14: Kt qu ca v d 8.12

8.6 CC B X L DNG (STREAM MANIPULATOR)


C++ cung cp cc b x l dng khc nhau m thc hin cc cng vic nh dng. Cc b x l dng cung cp cc kh nng nh n nh cc chiu rng trng, n nh chnh xc, n nh v khng n nh cc c nh dng, n nh lp y (fill) k t trong cc trng, flush dng, chn mt k t newline vo dng xut v flush dng, chn mt k t null vo dng xut v nhy khong trng trong dng nhp. 8.6.1 Cc b x l dec, oct, hex v setbase(): Cc s nguyn bnh thng c th hin cc gi tr thp phn (c s 10). thay i m cc s nguyn c th hin trn dng, chn b x l ios::hex n nh c s 16 hoc chn b x l ios::oct n nh c s 8. Chn b x l dng ios::dec xc lp li c s dng thp phn. C s ca dng cng c th thay i bi b x l dng setbase() c mt tham s l s nguyn vi cc gi tr: 0:Dng c s mc nh (c s 10). Trong trng hp ny mun nhp s dng bt phn, chng ta phi ghi ch s 0 pha trc s . 8: Dng c s 8. 10: Dng c s 10. 16: Dng c s 16. 324

V hm setbase() c mt tham s nn n c gi l mt b x l dng c tham s. S dng hoc bt k b x l dng c tham s no phi include tp tin <iomanip.h>. Trong file ny c ba lp lm mu OMANIP, IMANIP, v SMANIP ln lt cn cho vic nh ngha b x l c tham s trn dng xut, dng nhp v trn dng nhp/xut. Lp mu (class template) cn gi l lp chung chung (generic class). Gi nh vy l v lp c nh ngha vi nhiu yu t c b ng. Chng hn, lp OMANIP(class Type) c dng mt kiu d liu chung chung gi l Type. Khi Type thay bng kiu c th, chng hn OMANIP(int), chng ta c mt lp c th tng ng. V d 8.13:
CT8_13.CPP

1: //Chng trnh 8.13 2: #include <iostream.h> 3: #include <iomanip.h> 4: 5: int main() 6: { 7: int n; 8: cout << "Enter a decimal number: "; 9: cin >> n; 10: cout << n << " in hexadecimal is: " 11: 12: 13: 14: 15: 16: return 0; 17: } << hex << n << endl << dec << n << " in octal is: " << oct << n << endl << setbase(10) << n << " in decimal is: " << n << endl;

Chng ta chy v d 8.13, kt qu hnh 8.15

325

Hnh 8.15: Kt qu ca v d 8.13 8.6.2 chnh xc du chm ng (ios::precision(), setprecision()): Chng ta c th iu khin chnh xc ca cc s chm ng, ngha l s cc ch s bn phi du chm thp phn, bng cch s dng cc hm ios::precision() v setprecision(). Hm ios::precision(): (1) int precision(int np); (2) int precision(); Dng (2) tr v gi tri chnh xc hin gi. Dng (1) n nh chnh xc v tr v chnh xc gi tr chnh xc trc . Nu np bng 0 th khi phc chnh xc mc nh (l 6). Hm setprecision(): SMANIP(int) setprecision(int np); np cho bit chnh xc ca s chm ng. V d 8.14:
CT8_14.CPP

1: //Chng trnh 8.14 2: #include <iostream.h> 3: #include <iomanip.h> 4: #include <math.h> 5: 6: int main() 7: { 8: double Root2 = sqrt(2.0); 9: cout << "Square root of 2 with precisions 0-9." << endl 10: << "Precision set by the "

326

11:

<< "precision member function:" << endl;

12: for (int Places = 0; Places <= 9; Places++) 13: { 14: cout.precision(Places); 15: cout << Root2 << endl; 16: } 17: cout << endl << "Precision set by the " 18: << "setprecision manipulator:" << endl;

19: for (Places = 0; Places <= 9; Places++) 20: cout << setprecision(Places) << Root2 << endl; 21: return 0; 22: }

Chng ta chy v d 8.14, kt qu hnh 8.16

327

Hnh 8.16: Kt qu ca v d 8.14 8.6.3 rng trng (setw(), ios::width()): Hm ios::width(): (1) int width(int nw); (2) int width(); Dng (1) s n nh rng trng ni ti ca dng vi tham s nw. Khi rng l 0 (mc nh). Vic chn ch chn s cc k t cn thit biu din gi tr chn. Khi rng khc 0, vic chn n vo trng vi k t lp y ca dng, ln ti nw. Gi tr rng ni ti xc lp li 0 sau mi ln trch hoc chn. Dng (2) tr v gi tr hin ti ca bin rng ca dng. Hm setw(): SMANIP(int) setw(int nw); nw l s nguyn cho bit rng ca trng. 328

V d 8.15:
CT8_15.CPP

1: //Chng trnh 8.15 2: #include <iostream.h> 3: 4: int main() 5: { 6: int W = 4; 7: char St[10]; 8: cout << "Enter a sentence:" << endl; 9: cin.width(5); 10: while (cin >> St) 11: { 12: cout.width(W++); 13: cout << St << endl; 14: cin.width(5); 15: } 16: return 0; 17: }

Chng ta chy v d 8.15, kt qu hnh 8.17

329

Hnh 8.17: Kt qu ca v d 8.15 8.6.4 Cc b x l ngi dng nh ngha: Ngi dng c th to cc b x l dng cho ring mnh. nh ngha b x l khng tham s: istream & function_name (istream & in) { . return in; }

ostream & function_name (ostream & out) { . return out; } V d 8.16: B x l khng tham s.
CT8_16.CPP

330

1: //Chng trnh 8.16 2: #include <iostream.h> 3: 4: //B x l bell (s dng chui thot \a) 5: ostream& bell(ostream& output) 6: { 7: return output << '\a'; 8: } 9: 10: //B x l ret (s dng chui thot \r) 11: ostream& ret(ostream& output) 12: { 13: return output << '\r'; 14: } 15: 16: //B x l tab (su dung chuoi thoat \t) 17: ostream& tab(ostream& output) 18: { 19: return output << '\t'; 20: } 21: 22: //B x l endline (s dng chui thot \n v hm flush()) 23: ostream& endline(ostream& output) 24: { 25: return output << '\n' << flush; 26: } 27:

331

28: int main() 29: { 30: cout << "Testing the tab manipulator:" << endline 31: 32: 33: << 'a' << tab << 'b' << tab << 'c' << endline << "Testing the ret and bell manipulators:" << endline << "..........";

34: for (int I = 1; I <= 100; I++) 35: cout << bell; 36: cout << ret << "-----" << endline; 37: return 0; 38: }

Chng ta chy v d 8.16, kt qu hnh 8.18

Hnh 8.18: Kt qu ca v d 8.16 Mun nh ngha b x l c tham s, chng ta phi include tp tin <iomanip.h>. B x l c tham s trn dng xut c dng: ostream & function_name (ostream & out, parameter_type parameter) { . return out; } OMANIP(type) function_name (parameter_type parameter) { 332

return OMANIP(type) (function_name, parameter); } Tng t dng nh ngha b x l trn dng nhp v trn dng nhp/xut. V d 8.17: B x l c tham s.
CT8_17.CPP

1: //Chng trnh 8.17 2: #include <iostream.h> 3: #include <iomanip.h> 4: 5: ostream & indent(ostream & Stream,int Len) 6: { 7: for(int I=0;I<Len;++I) 8: cout<<" "; 9: return Stream; 10: } 11: 12: OMANIP (int) indent(int Len) 13: { 14: return OMANIP(int)(indent,Len); 15: } 16: 17: int main() 18: { 19: cout<<indent(10)<<"Hello"<<endl; 20: cout<<indent(20)<<"Peter"<<endl; 21: cout<<indent(5)<<"John"<<endl; 22: return 0; 23: }

333

Chng ta chy v d 8.17, kt qu hnh 8.19

Hnh 8.19: Kt qu ca v d 8.17

8.7 CC TRNG THI NH DNG DNG


Cc c nh dng khc nhau m t cc loi nh dng c thc thi trong sut qu trnh thao tc nhp/xut dng. Cc hm ios::setf(), ios::unsetf(), v ios::flags() iu khin cc thit lp c. Hm ios::setf(): (1) long setf(long lFlags); (2) long setf(long lFlags, long lMask); Trong : lFlags: nh dng cc gi tr bit c. C th kt hp cc bit c bng cch s dng ton t |. Cc bit c: Bit c ios::skipws ios::left ios::right ios::internal ios::dec ios::oct ios::hex ios::showbase ngha B qua khong trng trn nhp. Gi tr canh l tri; n thm bn phi vi k t lp y. Gi tr canh l phi; n thm bn tri vi k t lp y (mc nh). Thm cc k t lp y sau bt k du ch dn hoc du hiu c s no, nhng trc gi tr. Gi tr s nh dng theo c s 10 (mc nh). Gi tr s nh dng theo c s 8. Gi tr s nh dng theo c s 16. Hin th cc hng s theo dng m c th c bi trnh bin dch C++. 334

ios::showpoint ios::uppercase ios::showpos ios::scientific ios::fixed

Xut hin du thp phn v dng thc zero theo ui cho cc gi tr chm ng. Hin th ch hoa t A n F i vi gi tr h 16 v E i vi cc gi tr dng khoa hc. Hin th du + i vi cc s dng. Hin th s chm ng theo dng khoa hc. Hin th s chm ng theo dng c nh

lMask: nh dng mt n bit c. Hm tr v gi tr cc bit c trc . Hm ios::flags(): (1) long flags(long lFlags); (2) long flags(); Dng (2) tr v cc bit c hin ti ca dng. Dng (1) ging nh dng (1) ca hm ios::setf(). Hm ios::unsetf(): long unsetf(long lFlags); Hm xa cc bit c ch nh bi lFlags. Ngoi ra chng ta cn c hm setiosflags() ging nh dng (1) ca ios::setf() v hm resetiosflags() ging nh hm unsetf(). Cc c bit ios::left, ios::right,v ios::internal c cha trong bin thnh vin ios::adjustfield. Chng hn: ostream os; if( ( os.flags() & ios::adjustfield ) == ios::left ) ..... Tham s ios::adjustfield phi c cung cp nh tham s th 2 dng (2) ca hm ios::setf() khi n nh cc c bit cn l (ios::left, ios::right,v ios::internal). iu ny cho php ios::setf() bo m ch c mt trong ba c bit cn l c n nh. Chng hn: cout.setf(ios::left,ios::adjustfield); V d 8.18: C bit ios::showpoint. 335

CT8_18.CPP

1: //Chng trnh 8.18 2: #include <iostream.h> 3: #include <iomanip.h> 4: #include <math.h> 5: 6: int main() 7: { 8: cout << "cout prints 9.9900 as: " << 9.9900 << endl 9: 10: endl 11: << "cout prints 9.9000 as: " << 9.9000 << endl << "cout prints 9.0000 as: " << 9.0000 << endl <<

<< "After setting the ios::showpoint flag" << endl;

12: cout.setf(ios::showpoint); 13: cout << "cout prints 9.9900 as: " << 9.9900 << endl 14: 15: 16: return 0; 17: } << "cout prints 9.9000 as: " << 9.9000 << endl << "cout prints 9.0000 as: " << 9.0000 << endl;

Chng ta chy v d 8.18, kt qu hnh 8.20

Hnh 8.20: Kt qu ca v d 8.18 V d 8.19: C bit ios::left, ios::right, ios::internal. 336

CT8_19.CPP

1: //Chng trnh 8.19 2: #include <iostream.h> 3: #include <iomanip.h> 4: 5: int main() 6: { 7: int X = 12345; 8: cout << "Default is right justified:" << endl 9: 10: 11: << setw(10) << X << endl << endl << "USING MEMBER FUNCTIONS" << endl << "Use setf to set ios::left:" << endl << setw(10);

12: cout.setf(ios::left, ios::adjustfield); 13: cout << X << endl << "Use unsetf to restore default:" << endl; 14: cout.unsetf(ios::left); 15: cout << setw(10) << X << endl << endl 16: 17: 18: 19: 20: 21: << "USING PARAMETERIZED STREAM MANIPULATORS" << endl << "Use setiosflags to set ios::left:" << endl << setw(10) << setiosflags(ios::left) << X << endl << "Use resetiosflags to restore default:" << endl << setw(10) << resetiosflags(ios::left) << X << endl;

22: return 0; 23: }

Chng ta chy v d 8.19, kt qu hnh 8.21

337

Hnh 8.21: Kt qu ca v d 8.19 V d 8.20: C bit ios::showpos v ios::internal.


CT8_20.CPP

1: //Chng trnh 8.20 2: #include <iostream.h> 3: #include <iomanip.h> 4: 5: int main() 6: { 7: cout << setiosflags(ios::internal | ios::showpos) 8: << setw(10) << 123 << endl;

9: return 0; 10: }

Chng ta chy v d 8.20, kt qu hnh 8.22

338

Hnh 8.22: Kt qu ca v d 8.20 k t lp y chng ta dng hm ios::fill() v setfill(): Hm ios::fill(): (1) char fill(char cFill); (2) char fill(); Dng (1) n nh k t lp y ni ti v tr v k t lp y trc . Dng (2) tr v k t lp y ca dng. Hm setfill(): SMANIP(int) setfill(int nFill); V d 8.21: Hm ios::fill() v setfill().
CT8_21.CPP

1: //Chng trnh 8.21 2: #include <iostream.h> 3: #include <iomanip.h> 4: 5: int main() 6: { 7: int X = 10000; 8: cout << X 9: 10: 11: endl; << " printed as int right and left justified" << endl << "and as hex with internal justification." << endl << "Using the default pad character (space):" <<

12: cout.setf(ios::showbase); 13: cout << setw(10) << X << endl; 14: cout.setf(ios::left, ios::adjustfield); 15: cout << setw(10) << X << endl; 16: cout.setf(ios::internal, ios::adjustfield);

339

17: cout << setw(10) << hex << X << endl << endl; 18: cout << "Using various padding characters:" << endl; 19: cout.setf(ios::right, ios::adjustfield); 20: cout.fill('*'); 21: cout << setw(10) << dec << X << endl; 22: cout.setf(ios::left, ios::adjustfield); 23: cout << setw(10) << setfill('%') << X << endl; 24: cout.setf(ios::internal, ios::adjustfield); 25: cout << setw(10) << setfill('^') << hex 26: 27: return 0; 28: } << X << endl;

Chng ta chy v d 8.21, kt qu hnh 8.23

Hnh 8.23: Kt qu ca v d 8.21 V d 8.22: C bit ios::showbase.


CT8_22.CPP

1: //Chng trnh 8.22

340

2: #include <iostream.h> 3: #include <iomanip.h> 4: 5: int main() 6: { 7: int X = 100; 8: cout << setiosflags(ios::showbase) 9: endl 10: 11: 12: 13: return 0; 14: } << "Printing integers preceded by their base:" <<

<< X << endl << oct << X << endl << hex << X << endl;

Chng ta chy v d 8.22, kt qu hnh 8.24

Hnh 8.24: Kt qu ca v d 8.22 V d 8.23: Hin th cc gi tr chm ng theo dng mc nh h thng, dng khoa hc v dng c nh.
CT8_23.CPP

1: //Chng trnh 8.23 2: #include <iostream.h> 3: 4: int main()

341

5: { 6: double X = .001234567, Y = 1.946e 7: cout << "Displayed in default format:" << endl 8: << X << '\t' << Y << endl;

9: cout.setf(ios::scientific, ios::floatfield); 10: cout << "Displayed in scientific format:" << endl 11: << X << '\t' << Y << endl;

12: cout.unsetf(ios::scientific); 13: cout << "Displayed in default format after unsetf:" << endl 14: << X << '\t' << Y << endl;

15: cout.setf(ios::fixed, ios::floatfield); 16: cout << "Displayed in fixed format:" << endl 17: 18: return 0; 19: } << X << '\t' << Y << endl;

Chng ta chy v d 8.23, kt qu hnh 8.25

Hnh 8.25: Kt qu ca v d 8.23 V d 8.24: C bit ios::uppercase.


CT8_24.CPP

342

1: //Chng trnh 8.24 2: #include <iostream.h> 3: #include <iomanip.h> 4: 5: int main() 6: { 7: cout << setiosflags(ios::uppercase) 8: 9: 10: << "Printing uppercase letters in scientific" << endl << "notation exponents and hexadecimal values:" << endl << 4.345e10 << endl

11: << hex << 123456789 << endl; 12: return 0; 13: }

Chng ta chy v d 8.24, kt qu hnh 8.26

Hnh 8.26: Kt qu ca v d 8.24 V d 8.25: n nh v xc lp li cc c nh dng (ios::flags, setiosflags(), resetiosflags()).


CT8_25.CPP

1: //Chng trnh 8.25 2: #include <iostream.h> 3: int main() 4: { 5: int I = 1000;

343

6: double D = 0.0947628; 7: cout << "The value of the flags variable is: " 8: 9: 10: << cout.flags() << endl << "Print int and double in original format:" << endl << I << '\t' << D << endl << endl;

11: long originalFormat = cout.flags(ios::oct | ios::scientific); 12: cout << "The value of the flags variable is: " 13: 14: 15: endl 16: << cout.flags() << endl << "Print int and double in a new format" << endl << "specified using the flags member function:" <<

<< I << '\t' << D << endl << endl;

17: cout.flags(originalFormat); 18: cout << "The value of the flags variable is: " 19: 20: 21: << cout.flags() << endl << "Print values in original format again:" << endl << I << '\t' << D << endl;

22: return 0; 23: }

Chng ta chy v d 8.25, kt qu hnh 8.27

344

Hnh 8.27: Kt qu ca v d 8.25

8.8 CC TRNG THI LI DNG


Trng thi ca dng c th c kim tra thng qua cc bit trong lp ios-lp c s cho cc lp istream, ostream, v iostream chng ta s dng cho nhp/xut. Cc bit trng thi c nh ngha kiu lit k thuc lp ios nh sau: Bit trng thi ios::eofbit ios::failbit ios::badbit ios::goodbit Bt ln nu end-of-bit t n. Bt ln nu mt li nh dng xy ra trn dng nhng cc k t khng b mt. Bt ln nu c li nghim trng xy ra . Bt ln nu cc bit eofbit, failbit, v badbit khng bt ln. ngha

bit c trng thi ca cc bit, chng ta c hai cch c: Cch 1: Tng ng vi cc bit, chng ta c cc hm: Bit trng thi ios::eofbit Hm tng ng ios::eof() int eof(); ios::failbit ios::fail() int fail(); 345

ios::badbit

ios::bad() int bad();

ios::goodbit

ios::good() int good();

Cch 2:Dng hm ios::rdstate(): int rdstate(); Hm tr v trng thi li ca stream bi cc mt n: ios::eofbit, ios::failbit, ios::badbit, v ios::goodbit. xa bit trng thi no chng ta dng hm ios::clear(): void clear(int nState = 0); Trong nState=0 th tt c cc bit li u xa. Chng ta c th dng ton t | kt hp cc bit li. V d 8.26: Kim tra cc trng thi li.
CT8_26.CPP

1: //Chng trnh 8.26 2: #include <iostream.h> 3: 4: int main() 5: { 6: int X; 7: cout << "Before a bad input operation:" << endl 8: 9: 10: 11: 12: 13: << "cin.rdstate(): " << cin.rdstate() << endl << " cin.eof(): " << cin.eof() << endl << " cin.fail(): " << cin.fail() << endl << " cin.bad(): " << cin.bad() << endl << " cin.good(): " << cin.good() << endl << endl << "Expects an integer, but enter a character: ";

346

14: cin >> X; 15: cout << endl << "After a bad input operation:" << endl 16: 17: 18: 19: 20: << "cin.rdstate(): " << cin.rdstate() << endl << " cin.eof(): " << cin.eof() << endl << " cin.fail(): " << cin.fail() << endl << " cin.bad(): " << cin.bad() << endl << " cin.good(): " << cin.good() << endl << endl;

21: cin.clear(); 22: cout << "After cin.clear()" << endl 23: 24: 25: return 0; 26: } << "cin.fail(): " << cin.fail() << endl << "cin.good(): " << cin.good() << endl;

Chng ta chy v d 8.26, kt qu hnh 8.28

347

Hnh 8.28: Kt qu ca v d 8.26 Chng ta c th dng ton t ! trn dng nhp/xut, chng hn: if (!cin) { cout<<"Error input"<<endl; } Tuy nhin khng th vit: if (cin) { cout<<"OK!"<<endl; }

8.9 NHP XUT CC KIU NGI DNG NH NGHA


C++ c th nhp v xut cc kiu d liu chun s dng ton t trch dng >> v ton t chn dng <<. Cc ton t ny c a nng ha x l mi kiu d liu chun bao gm cc chui v cc a ch b nh. Lp 348

trnh vin c th a nng ha ton t trch dng v ton t chn dng thc hin nhp/xut cho cc kiu ngi dng nh ngha (Chng ta tm hiu k chng 4). V d 8.27:
CT8_27.CPP

1: //Chng trnh 8.27 2: #include <iostream.h> 3: 4: class PhoneNumber 5: { 6: private: 7: char AreaCode[4]; 8: char Exchange[4]; 9: char Line[5]; 10: friend ostream& operator <<(ostream& Output, PhoneNumber& Num); 11: friend istream& operator >>(istream& Input, PhoneNumber& Num); 12: }; 13: 14: ostream& operator <<(ostream& Output, PhoneNumber& Num) 15: { 16: Output << "(" << Num.AreaCode << ") " 17: << Num.Exchange << "-" << Num.Line; 18: return Output; 19: } 20: 21: istream& operator>>(istream& Input, PhoneNumber& Num) 22: { 23: Input.ignore(); //B qua (

349

24: Input.getline(Num.AreaCode, 4); 25: Input.ignore(2); //B qua ) v khong trng 26: Input.getline(Num.Exchange, 4); 27: Input.ignore(); //B qua 28: Input.getline(Num.Line, 5); 29: return Input; 30: } 31: 32: int main() 33: { 24: PhoneNumber Phone; 25: cout << "Enter a phone number in the " 26: << "form (123) 456-7890:" << endl;

27: cin >> Phone; 28: cout << "The phone number entered was:" << endl 29: 30: return 0; 31: } << Phone << endl;

Chng ta chy v d 8.27, kt qu hnh 8.29

Hnh 8.29: Kt qu ca v d 8.27

8.10 GN MT DNG XUT TI MT DNG NHP


350

C++ cung cp hm ios::tie() gn lin dng xut vi dng nhp. Vi hm dng xut s c lm sch trc khi c bt k php nhp no c thc hin trn dng nhp. Hm ny c dng: ostream* tie(ostream* pos); ostream* tie(); Chng hn: cin.tie(cout);

8.11 DNG NHP/ XUT FILE


thc thi x l file trong C++, cc chng trnh phi include tp tin <iostream.h> v <fstream.h>. Header <fstream.h> gm nh ngha cho cc lp dng ifstream cho nhp (c) t mt file, ofstream cho xut (ghi) ti mt file) v fstream cho nhp/xut (c/ghi) ti mt file. Cc file c m bng cch to cc i tng ca cc lp dng ny. Cy ph h ca cc lp ny hnh 8.2. Constructor ca lp ofstream: (1) ofstream(); (2) ofstream(const char* szName,int nMode=ios::out,int nProt=filebuf::openprot); (3) ofstream(int fd); (4) ofstream(filedesc fd, char* pch, int nLength); Trong : szName: Tn file c m. nMode: Mt s nguyn cha cc bit mode nh ngha l kiu liy k ca ios. C th kt hp bng ton t |. Tham s ny c th mt trong cc gi tr sau: Mode ios::app ngha Hm di chuyn con tr file ti end-of-file. Khi cc byte mi c ghi ln file, chng lun lun ni thm vo cui, ngay c v tr c di chuyn vi hm ostream::seekp(). Hm di chuyn con tr file ti end-of-file. Khi byte mi u tin c ghi ln file, chng lun lun ni thm vo cui, nhng khi cc byte k tip c ghi, chng ghi vo v tr hin hnh. M file c.Vi dng ifstream, vic m file ng nhin c thc hin ch ny. M file c.Vi dng ofstream, vic m file ng nhin 351

ios::ate

ios::in ios::out

c thc hin ch ny. ios::trunc Xa file hin c trn a v to file mi cng tn. Cng c hiu y l cht ct file c, lm cho kch thc ca n bng 0, chun b ghi ni dung mi. Mode ny c p dng nu ios::out c ch nh v ios::app, ios::ate, v ios::in khng c ch nh. Nu file khng tn ti th thao tc m tht bi. Nu file tn ti th thao tc m tht bi. M file ch nh phn (mc nh l ch vn bn). nProt: c t ch bo v file. fd: M nhn din file. pch: Con tr tr ti vng dnh ring chiu di nLength. Gi tr NULL (hoc nLength=0) dn n dng khng vng m. nLength: Chiu di tnh theo byte ca vng dnh ring (0=khng vng m). Dng (1) xy dng mt i tng ofstream m khng m file. Dng (2) xy dng mt i tng ofstream v m file ch nh. Dng (3) xy dng mt i tng ofstream v gn (attach) vi mt file m. Dng (4) xy dng mt i tng ofstream m lin kt vi i tng filebuf. i tng filebuf c gn ti file m v vng dnh ring. Constructor ca lp ifstream: (1) ifstream(); (2) ifstream(const char* szName,int nMode=ios::in,int nProt=filebuf::openprot); (3) ifstream(int fd); (4) ifstream(filedesc fd, char* pch, int nLength); Dng (1) xy dng mt i tng ifstream m khng m file. Dng (2) xy dng mt i tng ifstream v m file ch nh. Dng (3) xy dng mt i tng ifstream v gn (attach) vi mt file m. Dng (4) xy dng mt i tng ofstream m lin kt vi i tng filebuf. i tng filebuf c gn ti file m v vng dnh ring. 352

ios::nocreate ios::noreplace ios::binary

Constructor ca lp fstream: (1) fstream(); (2) fstream(const char* szName,int nMode,int nProt=filebuf::openprot); (3) fstream(int fd); (4) fstream(filedesc fd, char* pch, int nLength); Dng (1) xy dng mt i tng fstream m khng m file. Dng (2) xy dng mt i tng fstream v m file ch nh. Dng (3) xy dng mt i tng fstream v gn (attach) vi mt file m. Dng (4) xy dng mt i tng ofstream m lin kt vi i tng filebuf. i tng filebuf c gn ti file m v vng dnh ring. Nu chng ta s dng constructor dng (1) th chng ta dng hm open() m file: Hm ofstream::open(): void open(const char* szName,int nMode=ios::out,int nProt=filebuf::openprot); Hm ifstream::open(): void open(const char* szName,int nMode=ios::in,int nProt=filebuf::openprot); Hm fstream::open(): void open(const char* szName,int nMode,int nProt=filebuf::openprot); ng file chng ta dng hm close(), hm ny cc lp ifstream, ofstream, v fstream u c dng: void close(); Cc hm lin quan n con tr file: Lp istream: Hm seekg(): (seek get) (1) istream& seekg(streampos pos); (2) istream& seekg(streamoff off,ios::seek_dir dir); Trong : 353

+ pos: V tr mi. streampos l tng ng typedef vi long. + off: Gi tr offset mi. l tng ng typedef vi long. + dir: hng seek. C mt trong cc tr sau: ios::begin ios::cur ios::end Seek t bt u ca dng. Seek t v tr hin hnh ca dng Seek t cui ca dng

Hm tellg(): (tell get) streampos tellg(); Hm tr v v tr hin hnh ca con tr file. Lp ostream: Hm seekp(): (seek put) (1) ostream& seekp(streampos pos); (2) ostream& seekp(streamoff off,ios::seek_dir dir); Hm tellp(): (tell put) streampos tellp(); Hm tr v v tr hin hnh ca con tr file. 8.11.1 Nhp/xut file vn bn: Nu dng c gn vi file vn bn, vic nhp/xut file c thc hin mt cch n gin bi cc ton t >> v <<, ging nh khi chng ta lm vic vi cin v cout. File vn bn cha d liu dng m ASCII, kt thc bi k t EOF. V d 8.28: To file vn bn c th c s dng trong h thng c th nhn c cc ti khon gip qun l tin n bi cc khch hng tn dng ca cng ty. Mi khch hng, chng trnh cha mt s ti khon, tn v s d (balance).
CT8_28.CPP

1: //Chng trnh 8.28 2: #include <iostream.h> 3: #include <fstream.h>

354

4: #include <stdlib.h> 5: 6: int main() 7: { 8: ofstream OutClientFile("clients.dat", ios::out); 9: if (!OutClientFile) 10: { 11: cerr << "File could not be opened" << endl; 12: exit(1); 13: } 14: cout << "Enter the Account, Name, and Balance." << endl 15: << "Enter EOF to end input." << endl << "? ";

16: int Account; 17: char Name[10]; 18: float Balance; 19: while (cin >> Account >> Name >> Balance) 20: { 21: OutClientFile << Account << " " << Name 22: << " " << Balance << endl;

23: cout << "? "; 24: } 25: OutClientFile.close(); 26: return 0; 27: }

Chng ta chy v d 8.28, kt qu hnh 8.30

355

Hnh 8.30: Kt qu ca v d 8.28 V d 8.29: c file vn bn to v d 8.28 v xut ra mn hnh.


CT8_29.CPP

1: //Chng trnh 8.29 2: #include <iostream.h> 3: #include <fstream.h> 4: #include <iomanip.h> 5: #include <stdlib.h> 6: 7: void OutputLine(int, char*, float); 8: 9: int main() 10: { 11: ifstream InClientFile("clients.dat", ios::in); 12: if (!InClientFile) 13: { 14: cerr << "File could not be opened" << endl; 15: exit(1); 16: } 17: int Account; 18: char Name[10];

356

19: float Balance; 20: cout << setiosflags(ios::left) << setw(10) << "Account" 21: << setw(13) << "Name" << "Balance" << endl;

22: while (InClientFile >> Account >> Name >> Balance) 23: OutputLine(Account, Name, Balance); 24: InClientFile.close(); 25: return 0; 26: } 27: 28: void OutputLine(int Acct, char *Name, float Bal) 29: { 30: cout << setiosflags(ios::left) << setw(10) << Acct 31: 32: endl; 33: } << setw(13) << Name << setw(7) << setprecision(2) << setiosflags(ios::showpoint | ios::right) << Bal <<

Chng ta chy v d 8.29, kt qu hnh 8.31

Hnh 8.31: Kt qu ca v d 8.29 Do lp ifstream dn xut t lp istream nn chng ta c th dng cc hm istream::get(), istream::getline(). V d 8.30: c file vn bn to v d 8.28 bng hm istream::getline() v xut ra mn hnh. 357

CT8_30.CPP

1: //Chng trnh 8.30 2: #include <iostream.h> 3: #include <fstream.h> 4: #include <iomanip.h> 5: #include <stdlib.h> 6: 7: #define MAXLINE 256 8: 9: int main() 10: { 11: ifstream InClientFile("clients.dat", ios::in); 12: if (!InClientFile) 13: { 14: cerr << "File could not be opened" << endl; 15: exit(1); 16: } 17: char Line[MAXLINE]; 18: while (!InClientFile.eof()) 19: { 20: InClientFile.getline(Line,MAXLINE-1); 21: cout<<Line<<endl; 22: } 23: InClientFile.close(); 24: return 0; 25: }

Chng ta chy v d 8.30, kt qu hnh 8.32.(ni dung tp tin clients.dat) 358

Hnh 8.32: Kt qu ca v d 8.30 8.11.2 Nhp/xut file nh phn: i vi file nh phn (cn gi l file truy cp ngu nhin), chng ta m ch ios::binary. i vi file nh phn, chng ta c th dng hm istream::get() v ostream::put() c v ghi tng byte mt. c v ghi nhiu byte cng lc chng ta c th dng istream::read() v ostream::write(). V d 8.31: Ly li v d 8.28 nhng lu d liu di dng nh phn.
CT8_31.CPP

1: //Chng trnh 8.31 2: #include <iostream.h> 3: #include <fstream.h> 4: #include <stdlib.h> 5: 6: typedef struct 7: { 8: int Account; 9: char Name[10]; 10: float Balance; 11: }Client; 12: 13: int main() 14: { 15: ofstream OutClientFile("credit.dat", ios::out|ios::binary); 16: if (!OutClientFile) 17: {

359

18: cerr << "File could not be opened" << endl; 19: exit(1); 20: } 21: cout << "Enter the Account, Name, and Balance." << endl 22: 23: Client C; 24: while (cin >> C.Account >> C.Name >> C.Balance) 25: { 26: OutClientFile.write((char *)&C,sizeof(Client)); 27: cout << "? "; 28: } 29: OutClientFile.close(); 30: return 0; 31: } << "Enter EOF to end input." << endl << "? ";

Chng ta chy v d 8.31, kt qu hnh 8.33 (ni dung tp tin credit.dat)

Hnh 8.33: Kt qu ca v d 8.31 V d 8.32: c file to v d 8.31 v xut ra mn hnh.


CT8_32.CPP

1: //Chng trnh 8.32

360

2: #include <iostream.h> 3: #include <fstream.h> 4: #include <iomanip.h> 5: #include <stdlib.h> 6: 7: typedef struct 8: { 9: int Account; 10: char Name[10]; 11: float Balance; 12: }Client; 13: 14: void OutputLine(Client); 15: 16: int main() 17: { 18: ifstream InClientFile("credit.dat", ios::in|ios::binary); 19: if (!InClientFile) 20: { 21: cerr << "File could not be opened" << endl; 22: exit(1); 23: } 24: cout << setiosflags(ios::left) << setw(10) << "Account" 25: 26: Client C; 27: while (InClientFile.read((char *)&C,sizeof(Client))) 28: OutputLine(C); << setw(13) << "Name" << "Balance" << endl;

361

29: InClientFile.close(); 30: return 0; 31: } 32: 33: void OutputLine(Client C) 34: { 35: cout << setiosflags(ios::left) << setw(10) << C.Account 36: << setw(13) << C.Name << setw(7) << setprecision(2)

37: << setiosflags(ios::showpoint | ios::right)<< C.Balance << endl; 38: }

Chng ta chy v d 8.32, kt qu hnh 8.34

Hnh 8.34: Kt qu ca v d 8.32

9.1 TEMPLATE
Trong phn ny, chng ta tm hiu v mt trong cc c tnh cn li ca C++, l template (khun mu). Cc template cho php chng ta nh r, vi mt on m n gin, mt ton b phm vi ca cc hm c lin quan (a nng ha)gi l cc hm template-hoc mt ton b phm vi ca cc lp c lin quan-gi l lp template. Chng ta c th vit mt hm template n gin cho vic sp xp mt mng v C++ t ng pht sinh cc hm template ring bit m s sp xp mt mng int, sp xp mt mng float, Chng ta c th vit mt lp template cho lp stack v sau C++ t ng pht sinh cc lp template ring bit nh lp stack ca int, lp stack ca float, 9.1.1 Cc hm template: 362

Cc hm a nng ha bnh thng c s dng thc hin cc thao tc tng t trn cc kiu khc nhau ca d liu. Nu cc thao tc ng nht cho mi kiu, iu ny c th thc hin mch lc v thun tin hn s dng cc hm template. Lp trnh vin vit nh ngha hm template n gin. Da vo cc kiu tham s cung cp trong li gi hm ny, trnh bin dch t ng pht sinh cc hm m i tng ring bit x l mi kiu ca li gi thch hp. Trong C, iu ny c th c thc hin bng cch s dng cc macro to vi tin x l #define. Tuy nhin, cc macro biu th kh nng i vi cc hiu ng l nghim trng v khng cho php trnh bin dch thc hin vic kim tra kiu. Cc hm template cung cp mt gii php mch lc ging nh cc macro, nhng cho php kim tra kiu y . Chng hn, chng ta mun vit hm ly tr tuyt i ca mt s, chng ta c th vit nhiu dng khc nhau nh sau: int MyAbs(int X) { return X>=0?X:-X; } long MyAbs(long X) { return X>=0?X:-X; } double MyAbs(double X) { return X>=0?X:-X; } Tuy nhin vi cc hm ny chng ta vn cha c gii php tt, mang tnh tng qut nht nh hm c tham s kiu int nhng gi tr tr v l double v ngc li. Tt c cc hm template nh ngha bt u vi t kha template theo sau mt danh sch cc tham s hnh thc vi hm template vy quanh trong cc ngoc nhn (< v >); Mi tham s hnh thc phi c t trc bi t kha class nh: template <class T> hoc template <class T1, class T2,> Cc tham s hnh thc ca mt nh ngha template c s dng m t cc kiu ca cc tham s cho hm, m t kiu tr v ca hm, v khai bo cc bin bn trong hm. Phn nh ngha hm 363

theo sau v c nh ngha ging nh bt k hm no. Ch t kha class s dng m t cc kiu tham s ca hm template thc s ngha l "kiu c sn v kiu ngi dng nh ngha bt k". Khi , hm tr tuyt i trn vit theo hm template: template <class T> T MyAbs(T x) { return (x>=0)?x:-x; } Hm template MyAbs() khai bo mt tham s hnh thc T cho kiu ca mt s. T c tham kho nh mt tham s kiu. Khi trnh bin dch pht hin ra mt li gi hm MyAbs() trong chng trnh, kiu ca tham s th nht ca hm MyAbs() c thay th cho T thng qua nh ngha template, v C++ to mt hm template y tr v tr tuyt i ca mt s ca kiu d liu cho. Sau , hm mi to c bin dch. Chng hn: cout<<MyAbs(-2)<<endl; cout<<MyAbs(3.5)<<endl; Trong ln gi th nht, hm MyAbs() c tham s thc l int nn trnh bin dch to ra hm int MyAbs(int) theo dng ca hm template, ln th hai s to ra hm float MyAbs(float). Mi tham s hnh thc trong mt nh ngha hm template phi xut hin trong danh sch tham s ca hm ti thiu mt ln. Tn ca tham s hnh thc ch c th s dng mt ln trong danh sch tham s ca phn u template. V d 9.1: S dng hm template in cc gi tr ca mt mng c kiu bt k.
CT9_1.CPP

1: //Chng trnh 9.1 2: #include <iostream.h> 3: 4: template<class T> 5: void PrintArray(T *Array, const int Count) 6: { 7: for (int I = 0; I < Count; I++) 8: cout << Array[I] << " ";

364

9: 10: cout << endl; 11: } 12: 13: int main() 14: { 15: const int Count1 = 5, Count2 = 7, Count3 = 6; 16: int A1[Count1] = {1, 2, 3, 4, 5}; 17: float A2[Count2] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7}; 18: char A3[Count3] = "HELLO"; 19: cout << "Array A1 contains:" << endl; 20: PrintArray(A1, Count1); //Hm template kiu int 21: cout << "Array A2 contains:" << endl; 22: PrintArray(A2, Count2); //Hm template kiu float 23: cout << "Array A3 contains:" << endl; 24: PrintArray(A3, Count3); //Hm template kiu char 25: return 0; 26: }

Chng ta chy v d 9.1, kt qu hnh 9.1

Hnh 9.1: Kt qu ca v d 9.1 V d 9.2: Hm template c th c nhiu tham s. 365

CT9_2.CPP

1: //Chng trnh 9.2 2: #include <iostream.h> 3: 4: template<class T> 5: T Max(T a, T b) 6: { 7: return (a>b)?a:b; 8: } 9: 10: int main() 11: { 12: float A,B; 13: cout<<"Enter first number:"; 14: cin>>A; 15: cout<<"Enter second number:"; 16: cin>>B; 17: cout<<"Maximum:"<<Max(A,B); 18: return 0; 19: }

Chng ta chy v d 9.2, kt qu hnh 9.2

Hnh 9.2: Kt qu ca v d 9.2 Mt hm template c th c a nng ha theo vi cch. Chng ta c th cung cp cc hm template khc m m t cng tn hm nhng cc tham s hm khc nhau. Mt hm template cng c th c 366

a nng ha bi cung cp hm non-template vi cng tn hm nhng cc tham s hm khc nhau. Trnh bin dch thc hin mt x l so snh xc nh hm gi khi mt hm c gi. u tin trnh bin dch c gng tm v s dng mt i snh chnh xc m cc tn hm v cc kiu tham s i snh chnh xc. Nu iu ny tht bi, trnh bin dch kim tra nu mt hm template c m c th pht sinh mt hm template vi mt i snh chnh xc ca tn hm v cc kiu tham s. Nu mt hm template nh th c tm thy, trnh bin dch pht sinh v s dng hm template thch hp. Ch x l i snh ny vi cc template i yu cc i snh chnh xc trn tt c kiu tham s-khng c cc chuyn i t ng c p dng. 9.1.2 Cc lp template: Bn cnh hm template, ngn ng C++ cn trang b thm lp template, lp ny cng mang y tng ca hm template. Cc lp template c gi l cc kiu c tham s (parameterized types) bi v chng i hi mt hoc nhiu tham s m t lm th no ty chnh mt lp template chung to thnh mt lp template c th. Chng ta ci t mt lp Stack, thng thng chng ta phi nh ngha trc mt kiu d liu cho tng phn t ca stack. Nhng iu ny ch mang li s trong sng cho mt chng trnh v khng gii quyt c vn tng qut. Do chng ta nh ngha lp template Stack. V d 9.3: File TSTACK.H:
TSTACK.H

1: //TSTACK.H 2: //Lp template Stack 3: #ifndef TSTACK_H 4: #define TSTACK_H 5: 6: #include <iostream.h> 7: 8: template<class T> 9: class Stack 10: { 11: private: 12: int Size; //Kch thc stack 13: int Top;

367

14: T *StackPtr; 15: public: 16: Stack(int = 10); 17: ~Stack() 18: { 19: delete [] StackPtr; 20: } 21: int Push(const T&); 22: int Pop(T&); 23: int IsEmpty() const 24: { 25: return Top == -1; 26: } 27: int IsFull() const 28: { 29: return Top == Size - 1; 30: } 31: }; 32: 33: template<class T> 34: Stack<T>::Stack(int S) 35: { 36: Size = (S > 0 && S < 1000) ? S : 10; 37: Top = -1; 38: StackPtr = new T[Size]; 39: } 40:

368

41: template<class T> 42: int Stack<T>::Push(const T &Item) 43: { 44: if (!IsFull()) 45: { 46: StackPtr[++Top] = Item; 47: return 1; 48: } 49: return 0; 50: } 51: 52: template<class T> 53: int Stack<T>::Pop(T &PopValue) 54: { 55: if (!IsEmpty()) 56: { 57: PopValue = StackPtr[Top--]; 58: return 1; 59: } 60: return 0; 61: } 62: 63: #endif

File CT9_3.CPP:
CT9_3.CPP

1: //CT9_3.CPP

369

2: //Chng trnh 9.3 3: #include "tstack.h" 4: 5: int main() 6: { 7: Stack<float> FloatStack(5); 8: float F = 1.1; 9: cout << "Pushing elements onto FloatStack" << endl; 10: while (FloatStack.Push(F)) 11: { 12: cout << F << ' '; 13: F += 1.1; 14: } 15: cout << endl << "Stack is full. Cannot push " << F << endl 16: endl; << endl << "Popping elements from FloatStack" <<

17: while (FloatStack.Pop(F)) 18: cout << F << ' '; 19: cout << endl << "Stack is empty. Cannot pop" << endl; 20: Stack<int> IntStack; 21: int I = 1; 22: cout << endl << "Pushing elements onto IntStack" << endl; 23: while (IntStack.Push(I)) 24: { 25: cout << I << ' '; 26: ++I ; 27: }

370

28: cout << endl << "Stack is full. Cannot push " << I << endl 29: << endl << "Popping elements from IntStack" << endl;

30: while (IntStack.Pop(I)) 31: cout << I << ' '; 32: cout << endl << "Stack is empty. Cannot pop" << endl; 33: return 0; 34: }

Chng ta chy v d 9.3, kt qu hnh 9.3

Hnh 9.3: Kt qu ca v d 9.3 Hm thnh vin nh ngha bn ngoi lp template bt u vi phn u l template <class T> Sau mi nh ngha tng t mt nh ngha hm thng ngoi tr kiu phn t lun lun c lit k tng qut nh tham s kiu T. Chng hn: template<class T> int Stack<T>::Push(const T &Item) 371

{ . } Ngn ng C++ cn cho php chng ta to ra cc lp template linh ng hn bng cch cho php thay i gi tr ca cc thnh vin d liu bn trong lp. Khi lp c dng ca mt hm vi tham s hnh thc. V d 9.4: File TSTACK.H:
TSTACK.CPP

1: //TSTACK.H 2: //Lp template Stack 3: #ifndef TSTACK_H 4: #define TSTACK_H 5: 6: #include <iostream.h> 7: 8: template<class T,int Elements> 9: class Stack 10: { 11: private: 12: int Top; 13: T StackArray[Elements]; 14: public: 15: Stack(); 16: int Push(const T&); 17: int Pop(T&); 18: int IsEmpty() const 19: {

372

20: return Top == -1; 21: } 22: int IsFull() const 23: { 24: return Top == Elements - 1; 25: } 26: }; 27: 28: template<class T,int Elements> 29: Stack<T,Elements>::Stack() 30: { 31: Top = -1; 32: } 33: 34: template<class T,int Elements> 35: int Stack<T,Elements>::Push(const T &Item) 36: { 37: if (!IsFull()) 38: { 39: StackArray[++Top] = Item; 40: return 1; 41: } 42: return 0; 43: } 44: 45: template<class T,int Elements> 45: int Stack<T,Elements>::Pop(T &PopValue)

373

47: { 48: if (!IsEmpty()) 49: { 50: PopValue = StackArray[Top--]; 51: return 1; 52: } 53: return 0; 54: } 55: 56: #endif

File CT9_4.CPP:
CT9_4.CPP

1: //CT9_3.CPP 2: //Chng trnh 9.4 3: #include "tstack.h" 4: 5: int main() 6: { 7: Stack<float,5> FloatStack; 8: float F = 1.1; 9: cout << "Pushing elements onto FloatStack" << endl; 10: while (FloatStack.Push(F)) 11: { 12: cout << F << ' '; 13: F += 1.1; 14: }

374

15: cout << endl << "Stack is full. Cannot push " << F << endl 16: endl; << endl << "Popping elements from FloatStack" <<

17: while (FloatStack.Pop(F)) 18: cout << F << ' '; 19: cout << endl << "Stack is empty. Cannot pop" << endl; 20: Stack<int,10> IntStack; 21: int I = 1; 22: cout << endl << "Pushing elements onto IntStack" << endl; 23: while (IntStack.Push(I)) 24: { 25: cout << I << ' '; 26: ++I; 27: } 28: cout << endl << "Stack is full. Cannot push " << I << endl 29: << endl << "Popping elements from IntStack" << endl;

30: while (IntStack.Pop(I)) 31: cout << I << ' '; 32: cout << endl << "Stack is empty. Cannot pop" << endl; 33: return 0; 34: }

Chng ta chy v d 9.4, kt qu hnh 9.4

375

Hnh 9.4: Kt qu ca v d 9.4

9.2 X L EXCEPTION (EXCEPTION HANDLING)


X l exception l phng thc thng nht ca C++ gip lp trnh vin qun l theo cng mt phong cch i vi cc li pht sinh bi chng trnh vo lc chy. Nh phng thc ny, chng ta c th quy nh cc th tc cn c thc hin mt cch t ng trong tng trng hp li. im quan trng nht m phng thc x l exception l s bo m cho chng trnh khng chm dt tc thi, t ngt hoc nhy ti on m thc hin khng ng. 9.2.1 Cc t kha try, catch v throw: X l exception ca C++ dng ba cu lnh c thm vo ngn ng C++, l try, catch v throw. Ba t kha ny to nn mt c ch cho php cc chng trnh thng bo vi nhau v cc vn bt thng v nghim trng xy ra. Trong on m ca chng ta c ba ni tham gia vo vic pht hin exception: Khi try nh du on m m chng ta nghi ng c th xy ra sai lm khi chy. Khi catch nnm ngay lin sau khi try, cha on m lo gii quyt vn bt thng xy ra gi l exception handler. C th c nhiu lnh catch, mi lnh chuyn mt loi exception. Trong mi khi catch c th khai bo cho bit loi exception no chng ta mun gii quyt. Lnh throw l lm th no on m c vn thng bo exception handler bit vn phi gii quyt. Nu bt c ch no trong chng trnh, chng ta pht hin mt iu kin gy ra chng trnh phi thot khi try nhy v mt exception handler, chng ta c th nn ra exception ring ca chng ta bng cch dng lnh throw. Lnh throw s dng c php tng t nh lnh return cho php chng ta 376

nn ra bt c bin no c bit (hoc biu thc gn) m chng ta mun. Ch rng kiu bin chng ta nm ra phi khp vi kiu c khai bo trong khi catch u . try { . } catch(<exception declaration>) { . } catch(<exception declaration>) { . } V d 9.5: Minh ha cc t kha try, catch v throw (Cc chng trnh v exception phi chy trn Borland C++ 4.0 tr ln)
CT9_5.CPP

1: //Chng trnh 9.5 2: #include <iostream.h> 3: 4: int main() 5: { 6: cout<<"Start"<<endl; 7: try 8: { 9: cout<<"Inside block try"<<endl; 10: throw 100;

377

11: cout<<"This will not execute"<<endl; 12: } 13: catch(int I) 14: { 15: cout<<"Caught One! Number is "<<I<<endl; 16: } 17: cout<<"End"<<endl; 18: return 0; 19: }

Chng

ta chy v d 9.5, kt qu hnh 9.5

Hnh 9.5: Kt qu ca v d 9.5 Trong v d 9.5, khi try ch c vi cu lnh (dng 7 n 12), trong c lnh: throw 100; //Nm ra tr 100 tr ny s c bt bi khi catch ngay sau khi try. Chnh nh khi ny chng ta ng ph vi li xy ra. y chnh l exception handler. N ch in tr bt li c ra mn hnh. Sau hot ng ca exception handler, dng iu khin ca chng trnh khng tr v cu lnh dng 11 m tip tc vi cu lnh sau khi catch (dng 17). Nh vy mt sai lm xy ra, v mt exception c nm ra trong khi try th quyn iu khin s nhy v khi try v bt u d tm trn cc khi catch, khi catch no s gii quyt "bnh tnh" ca mnh (phn cn li ca khi try s khng c thi hnh). Nu khi catch no khp vi loi exception c nm ra th on m trong khi catch ny s c thi hnh, v vic thi hnh chm dt cui khi catch. Nu khng c khi catch no khp vi loi exception c nm ra th chng trnh s d tm trn call stack (stack cha cc hm c gi) i tm ln ln cp cao cc exception handler thch hp c tm thy. 378

Nu khng c exception no c nm ra th cc catch s khng c thi hnh (Hm terminate() c gi, hm ny mc nh gi hm abort()). Bin c khai bo trong cu lnh catch c th thuc bt c kiu d liu no chng ta mun nm ra. y c th l kiu d liu n gin (int, char *, ) hoc bt c lp no chng ta nh ngha. Ngoi ra chng ta c th s dng ba du chm () nh l kiu exception trong khi catch x l bt k kiu ca exception no v ch dng cui i vi mt khi try. Exception handler s dng ba du chm: catch() { .. } v c gi l ellipsis handler. Ch : Bn trong exception handler chng trnh c th tip tc hoc kt thc bng cch gi hm exit() hoc abort(). Nu bn trong khi try c i tng c to ra th khi chng trnh b i hng do lnh throw th i tng s b hy trc khi chng trnh b i hng. 9.2.2 Cc tnh hung x l exception:

Khi mt exception khng b bt

Nu mt exception c nm ra trong trng hp sau khi try khng c exception handler khng khp th hm terminate() c gi nhm kt thc chng trnh. V d 9.6:
CT9_6.CPP

1: //Chng trnh 9.6 2: #include <iostream.h> 3: 4: int main() 5: { 6: cout<<"Start"<<endl; 7: try

379

8: { 9: cout<<"Inside try block"<<endl; 10: throw 100; 11: cout<<"This will not execute"<<endl; 12: } 13: catch(long I) 14: { 15: cout<<"Caught One! Number is "<<I<<endl; 16: } 17: cout<<"End"<<endl; 18: return 0; 19: }

Chng ta chy v d 9.6, kt qu hnh 9.6

Hnh 9.6: Kt qu ca v d 9.6

Nm mt exception trong hm bt k

Chng ta c th nm mt exception t trong bt k hm no min l hm s c gi trong khi try. V d 9.7:


CT9_7.CPP

1: //Chng trnh 9.7 2: #include <iostream.h> 3:

380

4: void MyTest(int Test) 5: { 6: cout<<"Inside MyTest(), Test is "<<Test<<endl; 7: if (Test) 8: throw Test; 9: } 10: 11: int main() 12: { 13: cout<<"Start"<<endl; 14: try 15: { 16: cout<<"Inside try block"<<endl; 17: MyTest(0); 18: MyTest(1); 19: MyTest(2); 20: } 21: catch(int I) 22: { 23: cout<<"Caught One! Number is "<<I<<endl; 24: } 25: cout<<"End"<<endl; 26: return 0; 27: }

Chng ta chy v d 9.7, kt qu hnh 9.7

381

Hnh 9.7: Kt qu ca v d 9.7 Tr c nm ra khng phi l tr tr v ca hm v c th thuc kiu bt k tu chng ta chn (khng lin quan g n kiu tr v ca hm). Ch rng lnh return phc hi stack v trng thi trc khi gi hm, trong khi lnh throw ti lp stack nh trc khi vo khi try.

Khi try bn trong hm

Chng ta c th t khi try bn trong hm bt k x l exception lc chy sinh bi on m no thuc hm. V d 9.8:
CT9_8.CPP

1: //Chng trnh 9.8 2: #include <iostream.h> 3: 4: void MyHandler(int Test) 5: { 6: try 7: { 8: if (Test) 9: throw Test; 10: } 11: catch(int I) 12: { 13: cout<<"Caught One! Ex. #"<<I<<endl; 14: } 15: }

382

16: 17: int main() 18: { 19: cout<<"Start"<<endl; 20: MyHandler(1); 21: MyHandler(2); 22: MyHandler(0); 23: MyHandler(3); 24: cout<<"End"<<endl; 25: return 0; 26: }

Chng ta chy v d 9.8, kt qu hnh 9.8

Hnh 9.8: Kt qu ca v d 9.8

Nhiu khi catch

Chng ta c th to nhiu exception handler. Mi exception handler c nhim v bt mt exception thuc kiu no . V d 9.9:
CT9_9.CPP

1: //Chng trnh 9.9 2: #include <iostream.h> 3:

383

4: void MyHandler(int Test) 5: { 6: try 7: { 8: if (Test) 9: throw Test; 10: else 11: throw "Value is zero"; 12: } 13: catch(int I) 14: { 15: cout<<"Caught One! Ex. #"<<I<<endl; 16: } 17: catch(char *Str) 18: { 19: cout<<"Caught a string:"<<Str<<endl; 20: } 21: } 22: 23: int main() 24: { 25: cout<<"Start"<<endl; 26: MyHandler(1); 27: MyHandler(2); 28: MyHandler(0); 29: MyHandler(3); 30: cout<<"End"<<endl;

384

31: return 0; 32: }

Chng ta chy v d 9.9, kt qu hnh 9.9

Hnh 9.9: Kt qu ca v d 9.9

Bt exception c kiu bt k

Chng ta c th to ra mt exception handler c kh nng bt exception c ki bt k, y chnh l ellipsis handler. V d 9.10:


CT9_10.CPP

1: //Chng trnh 9.10 2: #include <iostream.h> 3: 4: void MyHandler(int Test) 5: { 6: try 7: { 8: if (Test==0) 9: throw Test; 10: if (Test==1) 11: throw 'a'; 12: if (Test==2)

385

13: throw 123.34; 14: if (Test==3) 15: throw "Test"; 16: } 17: catch(int) 18: { 19: cout<<"Caught int"<<endl; 20: } 21: catch(double) 22: { 23: cout<<"Caught double"<<endl; 24: } 25: catch(...) 26: { 27: cout<<"Caught One"<<endl; 28: } 29: } 30: 31: int main() 32: { 33: cout<<"Start"<<endl; 34: MyHandler(0); 35: MyHandler(1); 36: MyHandler(2); 37: MyHandler(3); 38: cout<<"End"<<endl; 39: return 0;

386

40: }

Chng ta chy v d 9.10, kt qu hnh 9.10

Hnh 9.10: Kt qu ca v d 9.10

Nn exception t mt exception handler

C++ cho php mt exception handler nm mt exception m n bt c. Mun vy, trong exception handler chng ta ch ghi cu lnh: throw; Bng cch nh vy, mt exception handler chuyn exception m n bt c cho khi try khc cha n. V d 9.11:
CT9_11.CPP

1: //Chng trnh 9.11 2: #include <iostream.h> 3: 4: void MyHandler() 5: { 6: try 7: { 8: throw "Hello!"; 9: } 10: catch(char *)

387

11: { 12: cout<<"Caught inside MyHandler()"<<endl; 13: throw; //Nm tip ra ngoi 14: } 15: } 16: 17: int main() 18: { 19: cout<<"Start"<<endl; 20: try 21: { 22: MyHandler(); 23: } 24: catch(char *) 25: { 26: cout<<"Caught inside main()"<<endl; 27: } 28: cout<<"End"<<endl; 29: return 0; 30: }

Chng ta chy v d 9.11, kt qu hnh 9.11

Hnh 9.11: Kt qu ca v d 9.11 388

Trong chng trnh v d 9.11, khi catch(char *) trong hm MyHandler() bt c mt chui v nm tip ra ngoi. Do vy, khi hm MyHandler() c gi bn trong khi try hm main(), khi catch(char *) trong hm main() li bt c chui . Vi c ch ny, chng ta c th to ra kh nng x l exception theo nhiu cp bng cu trc try/catch lng nhau. Nhng g cp di (catch bn trong) khng gii quyt th chuyn ln cp trn (catch bn ngoi) dt im.

Hn ch v kiu ca mt exception

Nh ni, exception c nm ra t trong mt hm khng c lin quan g n tr tr v ca hm . Exception c th thuc kiu ty . Tuy nhin, nu cn chng ta cng c th quy nh kiu ca exception. iu ny gi l c t exception (exception specification). thc hin hn ch, chng ta phi thm throw vo nh ngha hm. Dng tng qut: <return type> <function name> (<parameter list>) throw (<type list>) { } Trong ch c cc exception c kiu trong danh sch <type list> (phn cch bng du phy) l c nm ra t hm. Ngc li, vic nm ra cc exception thuc kiu khc l chng trnh kt thc bt thng (gi hm unexpected(), mc nh hm ny gi hm abort()). Nu <type list> rng th cm nm bt k ci g ra bn ngoi. Nu hm ang xt c tnh vi phm th chng trnh s kt thc ngay bi hm unexpected(). V d 9.12:
CT9_12.CPP

1: //Chng trnh 9.12 2: #include <iostream.h> 3: 4: void MyHandler(int Test) throw (int,char,double) 5: { 6: if (Test==0) 7: throw Test; 8: if (Test==1) 9: throw 'a';

389

10: if (Test==2) 11: throw 123.34; 12: } 13: 14: int main() 15: { 16: cout<<"Start"<<endl; 17: try 18: { 19: MyHandler(0); 20: } 21: catch(int) 22: { 23: cout<<"Caught int"<<endl; 24: } 25: catch(double) 26: { 27: cout<<"Caught double"<<endl; 28: } 29: catch(char) 30: { 31: cout<<"Caught char"<<endl; 32: } 33: cout<<"End"<<endl; 34: return 0; 35: }

390

Chng ta chy v d 9.12, kt qu hnh 9.12

Hnh 9.12: Kt qu ca v d 9.12 Ch rng quy nh va nu c hiu lc i vi exception nm ra khi hm tc l trong trng hp hm c gi bn trong mt khi try. i vi trng hp khi try t bn trong, exception c nm v bt bn trong hm vn khng b hn ch. 9.2.3 V d: V d 9.13: Chng trnh sau l mt v d v x l exception kim tra li "chia cho zero".
CT9_13.CPP

1: //Chng trnh 9.13 2: #include <iostream.h> 3: #include <string.h> 4: 5: //nh ngha mt lp DivideByZeroError s dng trong x l exception 6: //cho vic nm mt exception vi mt php chia cho zero. 7: class DivideByZeroError 8: { 9: private: 10: char Message[15]; 11: public: 12: DivideByZeroError() 13: { 14: strcpy(Message, "Divide by zero"); 15: } 16: void PrintMessage() const

391

17: { 18: cout << Message; 19: } 20: }; 21: 22: //nh ngha hm thng s. c s dng minh ha nm 23: //mt exception khi li chia cho zero bt gp 24: float Quotient(int Num1, int Num2) 25: { 26: if (Num2 == 0) 27: throw DivideByZeroError(); 28: return (float) Num1 / Num2; 29: } 30: 31: int main() 32: { 33: cout << "Enter two integers to get their quotient: "; 34: int Number1, Number2; 35: cin >> Number1 >> Number2; 36: try 37: { 38: float result = Quotient(Number1, Number2); 39: cout << "The quotient is: " << result << endl; 40: } 41: catch (DivideByZeroError Error) 42: { 43: cout << "ERROR: ";

392

44: Error.PrintMessage(); 45: cout << endl; 46: return 1; //Kt thc bi v c li 47: } 48: return 0; //Kt thc bnh thng 49: }

Chng ta chy v d 9.13, kt qu hnh 9.13

Hnh 9.13: Kt qu ca v d 9.13 Ton b cc v d v exception (t v d 9.5 n 9.13) c a vo mt project ca Borland C++ 4.0 vi tn file nn l Project_BC4.zip hoc workspace trong Visual C++ 6.0 vi tn file nn l Project_VC6.zip.

393

You might also like