background image

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

HOÏ C VIEÄ N CO NG NGHEÄ  BÖU CHÍ NH VIEàN THO NG 

CÔ SÔÛ   TAÏ I TP. HOÀ  CHÍ  MINH 

 
 
 
 
 
 

 Baø i 

giaûng: 

   
 

LAÄP TRÌNH  

HÖÔÙ NG ÑOÁ I TÖÔÏ NG 

 

Taø i lieä u duø ng cho heä  Ñaï i hoï c 

ngaø nh Coâ ng ngheä  thoâ ng tin & Ñieä n töû  – Vieã n thoâ ng 

ñaõ  ñöôï c Hoä i ñoà ng khoa hoï c Khoa Coâ ng ngheä  thoâ ng tin 2 

thoâ ng qua ngaø y 16/1/2002 

 

(Taäp 1) 

 
 
 

 

 

 

Bieân soaïn:

 

Th.S. NGUYEàN VIEÄ T CÖÔØ NG

 

 
 
 
 
 
 

 

LÖU HAØ NH NOÄ I BOÄ  

Tp. Hoà  Chí  Minh – Naê m 2002 

background image

 

  

 

ii 

Lôøi noùi ñaàu 

 

Baøi giaûng ñöôïc bieân soaïn döïa treân caùc taøi lieäu cuûa Herbert Schildt vaø Bjarne 
Stroustrup do coù tính sö phaïm cao vaø döïa treân moät soá taøi lieäu khaùc. 
 
Noäi dung baøi giaûng coù 12 chöông,  giôùi thieäu caùc khaùi nieäm caên baûn, caùc neàn taûng 
cuûa laäp trình höôùng ñoái töôïng (Object-Oriented Programming) bao goàm :  

• 

tính ñoùng goùi (Encapsulation) 

• 

tính keá thöøa (Inheritance)  

• 

tính ña hình (Polymorphism) 

• 

quaù taûi haøm vaø toaùn töû (Function & Operator Overloading) 

• 

template vaø ñieàu khieån ngoaïi leä (Exception Handling) 

• 

vaán ñeà phaùt trieån heä thoáng höôùng ñoái töôïng  

• 

minh hoïa moät soá öùng duïng cuûa laäp trình höôùng ñoái töôïng vôùi C++ trong moâi 

tröôøng DOS vaø Windows. 

 
Ngoân ngöõ laäp trình C++ ñöôïc söû duïng trong baøi giaûng nhaèm minh hoïa caùc yù töôûng 
cuûa laäp trình höôùng ñoái töôïng, do ñoù caùc kieán thöùc veà C++ ñöôïc trình baøy ñan xen 
trong moät soá chöông giuùp sinh vieân deã daøng lónh hoäi caùc khaùi nieäm khaù tröøu töôïng 
cuûa  laäp trình höôùng ñoái töôïng. 
 
Baøi giaûng khoâng coù tham voïng ñi saâu moïi khía caïnh cuûa laäp trình höôùng ñoái töôïng, 
chæ trình baøy caùc kieán thöùc caên baûn vaø qua caùc ví duï minh hoïa hy voïng seõ giuùp ích 
cho sinh vieân ngaønh coâng ngheä thoâng tin vaø ñieän töû vieãn thoâng böôùc ñaàu tìm hieåu theá 
giôùi laäp trình. 
 
Caùc ví duï minh hoïa ñaõ chaïy toát treân caùc trình bieân dòch Borland C++ 4.5 hoaëc Visual 
C++ 6.0 
 
Baøi giaûng ñöôïc phaân laøm hai taäp, taäp 1 töø chöông 1 ñeán chöông 8, taäp 2 töø chöông 9 
ñeán chöông 12. 
 
Raát mong caùc ñoàng nghieäp vaø caùc sinh vieân ñoùng goùp yù kieán xaây döïng ñeå baøi giaûng 
ñöôïc hoaøn thieän hôn trong caùc laàn soaïn thaûo veà sau.  

Thaùng 8 naêm 2001 

 
 

Th. S. Nguyeãn Vieät Cöôøng 
E-mail: nvc@ptithcm.edu.vn 

background image

 

  

 

iii 

Muïc luïc 

 

 
Taäp 1 

 
Chöông 1 

Toång quan veà Laäp trình höôùng ñoái töôïng

 

 

I.  Vaøi neùt veà söï phaùt trieån cuûa caùc ngoân ngöõ laäp trình............................1 

II.  Caùc khaùi nieäm cô baûn cuûa laäp trình höôùng ñoái töôïng ..........................4 

1. 

Lôùp vaø Ñoái töôïng (Class  & Object).........................................4 

2. 

Thoâng baùo (Message)...............................................................5 

3. 

Tính ñoùng goùi (Encapsulation) .................................................5 

4. 

Tính keá thöøa (Inheritance)........................................................6 

5. 

Tính ña hình (Polymorphism)...................................................7 

III.  Toång quan veà ngoân ngöõ laäp trình höôùng ñoái töôïng C++ .....................7 

1. 

Xuaát/Nhaäp (Console I/O) .........................................................7 

2. 

Chuù thích (Comment) .............................................................10 

3. 

Khaùi nieäm veà quaù taûi haøm (Function Overloading)................11 

4. 

Caùc töø khoaù (Keywords) trong C++........................................14 

 
 

Chöông 2 

Lôùp, Ñoái töôïng vaø Tính ñoùng goùi.................................

15 

 

I. Lôùp .................................................................................................17 

II.  Haøm taïo, haøm huûy ..........................................................................22 

III.  Tham soá cuûa haøm taïo .....................................................................30 

IV.  Noäi tuyeán töï ñoäng  ..........................................................................37 

V.  Gaùn ñoái töôïng .................................................................................39 

VI.  Truyeàn caùc ñoái töôïng sang haøm......................................................45 

VII.  Traû ñoái töôïng töø haøm ......................................................................53 

VIII. Haøm friend......................................................................................56 

IX.  Baøi taäp chöông 2 .............................................................................62 

 
 
Chöông 3 

Maûng , Con troû vaø Tham chieáu

.......................................67 

 

I.  Maûng caùc ñoái töôïng ........................................................................69 

II.  Con troû ñoái töôïng ............................................................................72 

background image

 

  

 

iv 

III. Con troû this......................................................................................75 

IV.  Toaùn töû new vaø delete ....................................................................78 

V. Tham chieáu (reference) ..................................................................86 

VI.  Truyeàn tham chieáu cho ñoái töôïng ...................................................91 

VII.  Traû veà caùc tham chieáu.....................................................................95 

VIII.  Caùc tham chieáu ñoäc laäp vaø caùc haïn cheá..........................................98 

IX.  Baøi taäp chöông 3 ...........................................................................100 

 
 
Chöông 4 

Quaù taûi haøm

.....................................................................103 

I.  Quaù taûi haøm taïo ...............................................................................105 

II.  Haøm taïo baûn sao ..............................................................................109 

III.  Söû duïng caùc ñoái soá maëc ñònh (default  argument) ...........................119 

IV.  Söï quaù taïi vaø tính khoâng xaùc ñònh (ambiguity)................................126 

V.  Ñiaï chæ cuûa haøm quaù taûi...................................................................130 

VI.  Baøi taäp chöông 4..............................................................................132 

 
 
Chöông 5 

Quaù taûi toaùn töû

.................................................................135

 

 

I.  Quaù taûi toaùn töû  ................................................................................137 

II.  Quaù taûi toaùn töû nhò nguyeân ..............................................................138 

III.  Quaù taûi toaùn töû quan heä & luaän lyù ...................................................144 

IV.  Quaù taûi toaùn töû ñôn nguyeân .............................................................146 

V.  Haøm toaùn töû friend...........................................................................149 

VI. Toaùn töû gaùn......................................................................................155 

VII.  Baøi taäp chöông 5..............................................................................158 

 
 
Chöông 6 

Tính keá thöøa

 ...................................................................163 

 

I.  Giôùi thieäu tính keá thöøa.....................................................................165 

II.  Ñieàu khieån truy caäp lôùp cô sôû..........................................................171 

III.  Söû duïng caùc thaønh vieân ñöôïc baûo veä ...............................................176 

IV.  Haøm taïo, haøm huûy vaø tính keá thöøa ..................................................181 

V.  Tính ña keá thöøa................................................................................189 

VI.  Lôùp cô sôû aûo.....................................................................................196 

VII.  Baøi taäp chöông 6..............................................................................201 

 

background image

 

  

 

Chöông 7 

Heä thoáng Nhaäp/Xuaát C++

 ............................................. 207 

 

I.  Cô sôû Nhaäp/Xuaát C++ ..................................................................... 209 

II.  Nhaäp/Xuaát coù ñònh daïng.................................................................. 210 

III.  Söû duïng width(), precision() vaø fill()............................................... 218 

IV.  Söû duïng boä thao taùc Nhaäp/Xuaát....................................................... 220 

V. Taïo boä cheøn..................................................................................... 223 

VI. Taïo boä chieát..................................................................................... 230 

VII.  Baøi taäp chöông 7.............................................................................. 234 

 
 
Chöông 8 

Nhaäp/Xuaát C++ naâng cao

.............................................. 237 

 

I.  Taïo Boä thao taùc Nhaäp/Xuaát............................................................. 239  

II. Nhaäp/Xuaát File................................................................................ 243 

III.  Nhaäp/Xuaát File nhò phaân khoâng ñònh daïng ..................................... 251 

IV.  Caùc haøm Nhaäp/Xuaát nhò phaân ......................................................... 258 

V.  Truy caäp ngaãu nhieân........................................................................ 261 

VI.  Kieåm tra traïng thaùi Nhaäp/Xuaát........................................................ 265 

VII.  Nhaäp/Xuaát theo ñôn ñaët haøng vaø caùc File....................................... 269 

VIII.  Nhaäp/Xuaát theo maûng ..................................................................... 272 

IX.  Baøi taäp chöông 8.............................................................................. 277 

 
 

Taäp 2 

 
Chöông 9 

Tính ña hình

.................................................................... 281

 

 

I.  Con troû  vaø Lôùp daãn xuaát ................................................................ 283 

II.  Daãn nhaäp caùc haøm aûo ...................................................................... 285 

III.  Caùc haøm aûo thuaàn tuùy...................................................................... 295 

IV.  AÙp duïng ña hình .............................................................................. 299 

V.  Baøi taäp chöông 9.............................................................................. 309 

 
 
Chöông 10 

Template vaø ñieàu khieån ngoaïi leä

 ................................. 311 

 

I. Haøm template.................................................................................. 313 

II. Lôùp template ................................................................................... 319 

background image

 

  

 

vi 

III.  Ñieàu khieån ngoaïi leä .........................................................................326 

IV. Bieán tónh ..........................................................................................339 

V.  Töø khoaù extern vaø asm ....................................................................344 

VI.  Haøm chuyeån kieåu.............................................................................346 

VII.  Nhöõng khaùc bieät giöõa C vaø C++ ......................................................349 

VIII.  Baøi taäp chöông 10............................................................................350 

 
 

Chöông 11 

Phaùt trieån caùc heä thoáng höôùng ñoái töôïng

......................351

 

 

I. Giôùi thieäu.........................................................................................353 

II.  Caùc moâ hình höôùng-thuû tuïc..............................................................354 

III.  Caùc coâng cuï phaùt trieån höôùng-thuû tuïc..............................................357 

IV.  Moâ hình höôùng ñoái töôïng.................................................................359 

V.  Caùc kyù hieäu vaø ñoà thò höôùng ñoái töôïng............................................361 

VI.  Caùc böôùc phaân tích höôùng ñoái töôïng ...............................................365 

VII.  Caùc böôùc thieát keá höôùng ñoái töôïng..................................................371 

VIII. Caøi ñaët .............................................................................................378 

IX.  Moâ hình nguyeân maãu.......................................................................379 

X. Toùm taét ............................................................................................380 

XI.  Baøi taäp chöông 11............................................................................381 

 

 
Chöông 12 

Moät soá öùng duïng OOP

....................................................383 

 

I.  ÖÙùng duïng treân moâi tröôøng DOS.......................................................385 

1. 

Sorted container example source file...................................385   

2. 

Text cross referencing example   .........................................389                                      

3. 

Updates and displays the contents of a mailing list..............398               

 

II.  ÖÙùng duïng treân moâi tröôøng WINDOWS ...........................................411 

1. 

Instructions for the IDE example MULTITRG.IDE.............411 

2. 

Common Dialogs example in C............................................419 

3. 

Demo True Type fonts..........................................................427 

4. 

Demo sound APIs  ................................................................447 

5. 

Creating a window application (TODO) ..............................456 

 

III.  Ñoà aùn moân hoïc.................................................................................479 

 

background image

 

  

 

vii 

Taøi lieäu tham khaûo 

 
Saùch giaùo khoa 

 
 
[1] Bjarne Stroustrup, 
 

What is 

Object-Oriented Programming” ? 

 

AT&T Bell Lab., 1991 (revised version), p1-21 

 

[2] Menachem Bazian, 
 

Fundamentals of Object-Oriented Programming

 

Microsoft Corp., 1995. 

 
[3] Herbert Schildt, 

Teach Yourself  C++, 3rd Edition, 

 McGraw-Hill, 

1997. 

 
[4]  H. M. Deitel & P. J. Deitel 
 

C++ How to Program, 2

nd

 edition, 

 

Prentice Hall, 1998 

 
[5] E. Balagurusamy, 
 

Object-Oriented Programming with C++,

 

 

Tata McGraw-Hill, 1997. 

 
 
 

Saùch tham khaûo 

 
 

[6] Herbert Schildt, 
 

C++ Nuts & Bolt : for Experienced Programmers

 McGraw-Hill, 

1997. 

 
[7] Herbert Schildt, 
 

C/C++ Programmer's Reference

 McGraw-Hill, 

1997. 

 
 

background image

 

  

 

viii 

[8] Bjarne Stroustrup, 
 

The C++ Programming Language, (3

rd

 Edition) 

 Addison-Wesley, 

1997 

 
[9] Bjarne Stroustrup, 
 

Why C++ is not just an Object-Oriented Programming Language,

 

 

AT&T Bell Lab., Murray Hill, New Jersay, 1995 , 13 pages 

  
[10] Bjarne Stroustrup, 
 

An  Overview of the C++ Programming Language

 

 

The Handbook of Object Technology, CRC Press LLC,  
Boca Raton, 1999, 23 pages 

 
[11] Bjarne Stroustrup, 
 

Learning Standard C++ as a New Language

 

AT&T Bell Lab., 1999, 11 pages  

 
[12] Jeri R. Hanly, 
 

Essential C++ for Engineers and Scientists

 Addison-Wesley, 

1997 

 
[13] Mark A. Terrible, 
 

Practical C++

 McGraw-Hill, 

1994. 

 
[14] Gordon Dodrill, 
 

C++ Tutorial

 

Coronado Enterprises, 1994. 

 
[15] IEEE Computer, 
 

“Open Channel” Interview with Bjarne Stroustrup

 IEEE, 

1998. 

 
[16] C. Thomas Wu, 
 

An Introduction to Object-Oriented Programming with JAVA

 McGraw-Hill, 

1999. 

 
[17]  Borland International, Inc.  
 

Borland C++, version 4.5, 1994. 

background image

 

 

 
Chöông 1   

 

Toång quan veà

 

laäp trình höôùng ñoái töôïng

 

 
 

 
 
 
 

Vaøi neùt veà söï phaùt trieån cuûa caùc ngoân ngöõ laäp trình 
 
 
Caùc khaùi nieäm cô baûn cuûa laäp trình höôùng ñoái töôïng 

• 

Lôùp vaø Ñoái töôïng (Class  & Object) 

• 

Thoâng baùo (Message) 

• 

Tính ñoùng goùi (Encapsulation) 

• 

Tính keá thöøa (Inheritance) 

• 

Tính ña hình (Polymorphism) 

 
 
Toång quan veà ngoân ngöõ laäp trình höôùng ñoái töôïng C++ 

• 

Xuaát/Nhaäp (Console I/O) 

• 

Chuù thích (Comment)   

• 

Khaùi nieäm veà quaù taûi haøm (Function Overloading) 

• 

Caùc töø khoaù (Keywords)  

 
 
 
 
 

background image

Chöông 1    Toång quan veà Laäp trình höôùng ñoái töôïng                                                                              

 

 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 1    Toång quan veà Laäp trình höôùng ñoái töôïng                                                                              

 

 

 

I/ Vaøi neùt veà söï phaùt trieån cuûa caùc ngoân ngöõ laäp trình 

 

Ngoân ngöõ laäp trình phaùt trieån qua hai lyù do : 
(1) ñeå thích öùng vôùi söï phaùt trieån cuûa moâi tröôøng (caùc heä maùy tính, caùc maïng). 
(2) boå sung toát hôn cho caùc phöông phaùp laäp trình. 
 

• 

Vaøo thaäp nieân 1940, chieác maùy tính ñieän töû ñaàu tieân ENIAC I (Electronic  

Numerical Integrator and Calculator

) ñöôïc cheá taïo taïi ÑH Pennsylvania, USA, 

bôûi nhoùm John W. Mauchly vaø J. Presper Eckert. Caùc chöông trình (program
luùc ñoù ñöôïc laäp ra baèng caùc quaù trình ñoùng môû caùc coâng taéc treân moät baûng ñaët 
tröôùc maùy tính. Ngoân ngöõ maùy (Machine language) vôùi nhöõng chuoåi nhò phaân 
0,1,... coù ñoä daøi qui öôùc chæ thích hôïp vôùi caùc chöông trình  nhoû nhaát. 

 

• 

Sau ñoù John von Neumann (ÑH Princeton, USA) ñaõ ñeà xuaát khaùi nieäm chöông 

trình löu tröõ 

trong boä nhôù maùy tính, yù töôûng naøy khoâng nhöõng caûi tieán toác ñoä tính 

toaùn cuûa maùy tính luùc ñoù maø coøn gôïi ra nhöõng phöông phaùp linh hoaït ñeå vieát caùc 
chöông trình trong töông lai. Hôïp ngöõ (Assembly language) ñöôïc taïo ra cho pheùp 
vieát caùc chöông trình daøi hôn. 

 

• 

Cuoái thaäp nieân 1950 vaø ñaàu thaäp nieân 1960, caùc ngoân ngöõ caáp cao ñaõ ra ñôøi nhö 

FORTRAN (FORmula TRANslator) duøng cho caùc tính toaùn  veà toaùn hoïc vaø 
COBOL (COmmon Business Oriented Language) duøng trong lónh vöïc thöông 
maïi. Ngoân ngöõ BASIC (Beginners All-purpose Symbolic Instructional Code
ñöôïc phaùt trieån laàn ñaàu tieân treân caùc maùy vi tính (micro-computer) nhaèm giuùp 
caùc sinh vieân deã hoïc vaø tieáp caän vôùi caùc chöông trình maùy tính. 

 

Caùc ngoân ngöõ laäp trình coù caáu truùc nhö ALGOL vaø PASCAL ra ñôøi giuùp loaïi boû 
caùc nhöôïc ñieåm nhö roái loaïn maõ khoù quaûn lyù khi soá leänh trong chöông trình daøi 
haøng ngaøn doøng.  

 

• 

Ñaàu thaäp nieân 1970 ngoân ngöõ C (do Denis Ritchie) ñöôïc ra ñôøi taïi AT&T Bell 

Labs, USA. Ngoân ngöõ C toång hôïp caùc söùc maïnh cuûa caùc ngoân ngöõ laäp trình caáu 
truùc khaùc, deå hieåu, deå hoïc vaø trôû neân phoå bieán vôùi moïi ngöôøi. Thaùng 12/1989, 
ngoân ngöõ C ñöôïc ANSI (American National Standards Insitute) chuaån hoaù vaø 
thoâng qua. 

 
 

background image

Chöông 1    Toång quan veà Laäp trình höôùng ñoái töôïng                                                                              

 

 

 

• 

Laäp trình coù caáu truùc (hay coøn goïi laø laäp trình thuû tuïc)

 döïa vaøo caùc caáu truùc ñieàu 

khieån (for, while, do, if, ...) ñaõ ñöôïc ñònh nghiaõ, caùc khoái maõ leänh, ít duøng leänh 
GOTO,  caùc chöông trình con hoã trôï pheùp ñeä qui vaø caùc bieán cuïc boä.  

 

 

 

Main program 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Function 1 

 

Function 2 

 

Function 3 

 

 

 

 

 

 

 

 

 

 

 

 

 

 Function 

 Function 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Function 6 

 

Function 7 

 

Function 8 

 

Hình 1.1

  

Caùc chöông trình höôùng-thuû tuïc (laäp trình caáu truùc) 

 
 
Moät chöông trình lôùn ñöôïc chia thaønh nhieàu chöông trình con cho nhieàu nhoùm laäp 
trình khaùc nhau cuøng laøm vieäc, vôùi soá doøng leänh ñeán vaøi chuïc ngaøn doøng, giuùp deã 
daøng baûo trì vaø phaùt trieån phaàn meàm. 

 
 
 

 Global 

Data 

 Global 

Data 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Function-1 

 

Function-2 

 

Function-3 

 

Local Data 

 

Local Data 

 

Local Data 

 

Hình 1.2

  

Quan heä giöõa döõ lieäu vaø haøm trong laäp trình höôùng-thuû tuïc 

 

• 

Ñaàu thaäp nieân 1980, ngoân ngöõ C++ (döïa treân ngoân ngöõ C, Bjarne Stroustrup 

giôùi thieäu

) vaø ngoân ngöõ Smalltalk (Xerox PARK) ñöôïc phaùt trieån nhaèm hoå trôï 

cho phöông phaùp laäp trình höôùng ñoái töôïng (Object Oriented Programming), 
phöông phaùp naøy ñaõ ñöôïc ñeà xuaát töø cuoái thaäp nieân 1960 vôùi ngoân ngöõ Simula. 
C++ ñöôïc chuaån hoaù vaøo thaùng 11/1997 vaø moät chuaån ANSI/ISO ñaõ coâng boá. 

 

background image

Chöông 1    Toång quan veà Laäp trình höôùng ñoái töôïng                                                                              

 

 

 

Laäp trình höôùng ñoái töôïng söû duïng C++ taïo neân söï bieán ñoåi saâu saéc, giuùp laäp 
trình vieân coù theå quaûn lyù nhöõng chöông trình lôùn vaø phöùc taïp (hôn 100.000 doøng 
leänh). 

• 

Thaäp nieân 1990, vôùi söï phaùt trieån maïnh meõ cuûa maïng World Wide Web, moät 

cuoäc caùch maïng môùi trong kyõ thuaät laäp trình ñaõ xaûy ra. Ngoân ngöõ JAVA do 
James Gosling, Patrick Naughton, Christ Warth, vaø Mike Sheridan phaùt trieån taïi 
haõng Sun Microsystem. Teân chính thöùc ñöôïc coâng boá vaøo naêm 1995.  

 

• 

JAVA laø ngoân ngöõ laäp trình höôùng ñoái töôïng khoâng phuï thuoäc vaøo thieát bò (caùc 

boä vi xöû lyù, heä ñieàu haønh, maïng, ...). JAVA ñöôïc thieát keá khoâng phaûi ñeå thay 
theá C++, maø ñeå giaûi quyeát nhöõng vaán ñeà ñang ñaët ra cho neàn coâng ngheä tin hoïc. 

 

• 

Phöông phaùp laäp trình höôùng ñoái töôïng

 cho pheùp phaân chia moät baøi toaùn thaønh 

caùc nhoùm nhoû coù quan heä vôùi nhau. Moãi nhoùm laø moät ñoái töôïng chöùa caùc leänh vaø 
döõ lieäu rieâng cuûa noù coù quan heä vôùi ñoái töôïng ñoù

.  

 

Nhôø ñoù, tính phöùc taïp cuûa chöông trình ñöôïc giaûm xuoáng, ngöôøi laäp trình coù theå 
quaûn lyù nhöõng chöông trình raát lôùn, chaúng haïn heä ñieàu haønh Windows vaø nhöõng 
chöông trình öùng duïng treân ñoù laø nhöõng minh chöùng cho phöông phaùp naøy.  

 

  Object  A   

 

 

 

 Object  B 

 

 

 

 

 

 

 

 

 

 

Data 

 

 

 

Data 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Functions   

 

 

Functions   

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    Object 

 

     

 

 

 

 

 

 

 

 

 

 

 

 

Functions   

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Data 

 

 

 

 

 

 

 

 

 

 

 

Hình 1.3    

Toå chöùc cuûa döõ lieäu vaø caùc phöông thöùc trong laäp trình höôùng-ñoái töôïng 

 

Caùc ñaëc tính quan troïng trong laäp trình höôùng ñoái töôïng :  

background image

Chöông 1    Toång quan veà Laäp trình höôùng ñoái töôïng                                                                              

 

 

 

• 

Tính ñoùng goùi (Encapsulation) 

• 

Tính keá thöøa (Inheritance) 

• 

Tính ña hình (Polymorphism) 

 
 
II/ Caùc khaùi nieäm cô baûn cuûa laäp trình höôùng ñoái töôïng 

 

1/ Lôùp (Class) vaø Ñoái töôïng (Object) 
Caùc ñoái töôïng laø caùc thöïc theå (entities) cô sôû khi chaïy chöông trình (run-time) trong 
moät heä thoáng höôùng ñoái töôïng

.  

 
Chuùng coù theå bieåu dieãn moät con ngöôøi, moät vò trí, moät taøi khoaûn ngaân haøng, moät 
baûng döõ lieäu hoaëc baát kyø moät ñeà muïc (item) naøo maø chöông trình caàn duøng ñeå thöïc 
hieän caùc taùc vuï (tasks).          

 
 

Object : SINHVIEN     

SINHVIEN 

 

DATA 

 

 

   

 

    Teân 

 

Nhaäp() 

 

 

 

    Ngaøy sinh 

 

 

 

 

 

 

    Ñieåm  

 

 

 

 

 

 

    .... 

 

TrungBình() 

 

 

 

FUNCTIONS 

 

 

   

 

    Nhaäp() 

 

 

 

 

 

 

    TrungBình() 

 

HieånThò() 

 

 

       HieånThò() 

 

 

 

 

 

 (a) 

 

 

 (b) 

 

 

                      Hình 1.4              Hai caùch bieåu dieãn moät ñoái töôïng 

 

Beân trong moät chöông trình coù theå vieát caùc doøng leänh (instructions) ñeå taïo ra caùc ñoái 
töôïng. Ñeå maùy tính coù theå taïo ra ñoái töôïng, chuùng ta caàn phaûi cung caáp moät ñònh 
nghiaõ, goïi laø lôùp. 
 
Lôùp laø moät daïng khuoân (mould , template) qua ñoù chöông trình maùy tính duøng ñeå taïo 
ra caùc ñoái töôïng.

  

 
Moät ñoái töôïng ñöôïc goïi laø moät theå hieän (instance) cuûa moät lôùp. Moät ñoái töôïng laø moät 
theå hieän chính xaùc

 cuûa moät lôùp.  

Khi ñònh nghiaõ moät lôùp, coøn ñöôïc xem laø taïo ra moät kieåu döõ lieäu môùi töø ngöôøi duøng.  

background image

Chöông 1    Toång quan veà Laäp trình höôùng ñoái töôïng                                                                              

 

 

 

 
Khi khai baùo moät ñoái töôïng, coù nghiaõ laø taïo ra moät bieán coù kieåu döõ lieäu laø moät lôùp.   
 
Caùc  thaønh vieân (members) cuûa moät lôùp bao goàm döõ lieäu (data) vaø caùc haøm hay 
phöông thöùc (function, method) 

 

Nguyeân  

 
 

SINHVIEN   

 

 

 

 

 
 

 

 

 

 

 

         Hanh   

 

 

 

 

 

 

        

 

 

 

 

 

 

            

 

 

 

 

 

 

 

 Class 

  Instances 

  

 

Objects 

   

 

 

 

 

Hình 1.5

 

       Lôùp SINHVIEN vaø 2 ñoái töôïng Nguyeân  &  Hanh 

 
 

2/ Thoâng baùo (Message) 
Ñeå yeâu caàu moät ñoái töôïng thöïc thi moät taùc vuï, caàn gôûi moät thoâng baùo ñeán noù.  
Chaúng haïn, chuùng ta gôûi moät thoâng baùo new ñeán lôùp SINHVIEN ñeå taïo ra moät theå 
hieän (moät ñoái töôïng SINHVIEN), sau ñoù gôûi moät thoâng baùo Nhaäp() ñeán ñoái töôïng 
cuûa lôùp SINHVIEN ñeå nhaäp caùc döõ lieäu veà sinh vieân. 
 
 
3/ Tính ñoùng goùi (Encapsulation) 
Vieäc toå chöùc döõ lieäu (data) vaø caùc haøm (function) hay phöông thöùc (method) trong 
moät ñôn vò duy nhaát (goïi laø lôùp) ñöôïc xem laø tính chaát ñoùng goùi.  
 
Ñoùng goùi döõ lieäu

 (Data Encapsulation) laø moät trong nhöõng ñaëc tính noåi baät cuûa moät 

lôùp. Döõ lieäu khoâng theå truy xuaát ñöôïc ôû beân ngoaøi lôùp vaø chæ nhöõng phöông thöùc beân 
trong lôùp ñoù môùi coù theå truy xuaát ñöôïc chuùng.  
 
Trong moät ñoái töôïng, döõ lieäu vaø haøm hoaëc caû hai coù theå laø rieâng  cuûa ñoái töôïng ñoù 
hoaëc chung.  

SINHVIEN 

SINHVIEN 

background image

Chöông 1    Toång quan veà Laäp trình höôùng ñoái töôïng                                                                              

 

 

 

 
Döõ lieäu vaø haøm rieâng laø thuoäc veà ñoái töôïng ñoù vaø chæ ñöôïc truy caäp bôûi caùc thaønh 
phaàn beân trong cuûa ñoái töôïng. 
 
Vôùi döõ lieäu vaø haøm chung, caùc boä phaän khaùc cuûa chöông trình coù theå truy caäp ñeán 
chuùng. 
 
Nhöõng chöùc naêng naøy cung caáp moät giao tieáp giöõa döõ lieäu cuûa ñoái töôïng vaø chöông 
trình. Söï caùch ly naøy cuûa döõ lieäu töø vieäc truy xuaát tröïc tieáp bôûi chöông trình ñöôïc goïi 
laø söï che daáu döõ lieäu (data hiding) 
 
 
4/ Tính keá thöøa (Inheritance) 
Tính keá thöøa laø quaù trình moät ñoái töôïng coù theå coù ñöôïc caùc tính chaát cuûa moät ñoái 
töôïng khaùc

. Nghiaõ laø, moät ñoái töôïng coù theå keá thöøa caùc tính chaát toång quaùt ñeå boå 

sung theâm caùc ñaëc ñieåm cuûa noù.  
 
Tính keá thöøa hoå trôï khaùi nieäm phaân loaïi theo thöù baäc (hierarchical classification) , 
ñoùng vai troø quan troïng trong laäp trình höôùng ñoái töôïng. 

 
 
 
 
 
 
 
 
 

 

Hình 1.6 

Heä thoáng thöù baäc keá thöøa (ñôn giaûn) trong Hoïc vieän  

 
 
Lôùp cô sôû (base class)  

      : “Hoïc Vieän  Coâng ngheä  Böu Chính –Vieãn Thoâng” 

Lôùp daãn xuaát (derived class)  :   “Khoái Sinh vieân”  , 
     “Khoái 

Giaùo 

vieân” 

 

     “Khoái 

Nhaân 

vieân” 

5/ Tính ña hình (Polymorphism) 

Hoïc Vieän  Coâng ngheä  Böu Chính –Vieãn Thoâng 

Khoái Sinh vieân 

Khoái Giaùo vieân 

Khoái Nhaân vieân 

background image

Chöông 1    Toång quan veà Laäp trình höôùng ñoái töôïng                                                                              

 

 

 

Tính ña hình laø tính chaát cho pheùp moät teân (ñoái töôïng, haøm, toaùn töû) ñöôïc duøng cho 
hai hay nhieàu muïc ñích khaùc nhau coù quan heä veà phöông dieän kyõ thuaät

 
Tính ña hình cho pheùp thöïc hieän quaù taûi haøm (function overloading) hay quaù taûi toaùn 
töû

 (operator overloading) 

 
Tính ña hình theå hieän yù töôûng "moät giao dieän cho nhieàu phöông thöùc". 

 
 
 

III/ Toång quan veà ngoân ngöõ laäp trình höôùng ñoái töôïng C++ 

 

Do C++ ñöôïc xaây döïng töø ngoân ngöõ C vôùi lôùp, neân moïi phaàn töû cuûa C ñeàu ñöôïc chöùa 
trong C++ . 
 
Caùc haøm caên baûn cuûa C++ ñeàu chöùa trong thö vieän iostream.h 
 
 
1/ Xuaát/Nhaäp trong C++  (Console I/O) 
 
Töø khoaù cout, cin laø caùc stream ñöôïc ñònh nghiaõ tröôùc trong iostream.h, töï ñoäng lieân 
keát vôùi console khi chöông trình C++ baét ñaàu chaïy.  
 
cout

 töông ñöông vôùi stdout, vaø cin töông ñöông vôùi stdin trong ngoân ngöõ C. 

 
Cuù phaùp  
 

cout <<

  expression 

// xuaát noäi dung cuûa bieåu thöùc ra maøn hình 

 

cin   >>

  variable ;   

// nhaäp moät giaù trò töø baøn phím vaøo bieán variable 

 
vôùi     <<     

toaùn töû xuaát 

 

>>     

toaùn töû nhaäp 

 

expression

  bieåu thöùc C++ baát kyø 

variable 

 bieán 

 
 
 
Ví duï 1.1  

background image

Chöông 1    Toång quan veà Laäp trình höôùng ñoái töôïng                                                                              

 

 

 

10 

#include <iostream.h> 
 
int main() 

  int i = 10,  j = 20;   

 double d = 99.101; 

 
  cout << "Here are some values: "; 
  cout << i; 
  cout << ' '; 
  cout << j; 
  cout << ' '; 
  cout << d; 
  return 0; 

 
Ví duï 1.2

 

Xuaát nhieàu hôn moät giaù trò trong moät bieåu thöùc  nhaäp/xuaát ñôn 

 
#include <iostream.h> 
int main() 

  int i,  j; 

  double d; 

 
  i = 10; 
  j = 20; 
  d = 99.101; 
 
  cout << "Here are some values: "; 
  cout << i << ' ' << j << ' ' << d; 
 
  return 0; 

 
 
Ví duï 1.3

 

Khi nhaäp, caùc muïc rieâng leû phaûi caùch nhau khoaûng traéng.  

Vôùi chuoåi, toaùn töû nhaäp seõ ngöøng khi gaëp kyù töï  khoaûng traéng ñaàu tieân

 
#include <iostream.h> 

background image

Chöông 1    Toång quan veà Laäp trình höôùng ñoái töôïng                                                                              

 

 

 

11 

 
int main() 

  int i;  float f;  char s[80]; 
 
  cout << "Enter an integer, float, and string: "; 
  cin >> i >> f >> s; 
 
  cout << "Here's your data: "; 
  cout << i << ' ' << f << ' ' << s; 
 
  return 0; 

 
 
Ví duï 1.4 

Vôùi toaùn töû nhaäp >> ,  moïi döõ lieäu nhaäp ñöôïc ñöa vaøo boä ñeäm (buffer) 

cho ñeán khi nhaán phím ENTER. 
 
#include <iostream.h> 
 
int main() 

  char ch; 
  cout << "Enter keys, x to stop.\n"; 
 
  do { 
    cout << " : "; 
    cin >> ch; 
  } while (ch != 'x'); 
 
  return 0; 

 
 
2/ Chuù thích (comment)  trong C++ 

• 

Chuù thích moät doøng leänh 

 

//  ... 

Ví duï 1.5 

Xaùc ñònh moät soá nguyeân laø soá chaün hay leû 

background image

Chöông 1    Toång quan veà Laäp trình höôùng ñoái töôïng                                                                              

 

 

 

12 

#include <iostream.h> 
 
int main() 

  int num;  // this is a C++, single-line comment 
 
  // read the number   
  cout << "Enter number to be tested: "; 
 
  cin >> num; 
 
  // see if even or odd 
  if((num%2)==0) cout << "Number is even\n"; 
  else cout << "Number is odd\n"; 
 
  return 0; 

 

• 

Chuù thích nhieàu doøng leänh   

/*   ...  */ 

 

Ví duï 1.6 

/* This is a multiline comment 
   inside of which // is nested a single-line comment. 
   Here is the end of the multiline comment. 
*/ 

 
 
3/ Khaùi nieäm veà quaù taûi haøm (Function Overloading) 
 
Hai hoaëc nhieàu haøm duøng chung moät teân. Coù 3 loaïi : 

• 

Cuøng soá ñoái soá 

• 

Khaùc soá ñoái soá 

• 

Khaùc soá ñoái soá vaø khaùc kieåu döõ lieäu 

 
Muïc ñích :  

• 

giuùp giaûm bôùt tính phöùc taïp cuûa chöông trình baèng caùch cho pheùp caùc pheùp toaùn 

coù lieân heä ñöôïc tham chieáu cuøng moät teân. 

background image

Chöông 1    Toång quan veà Laäp trình höôùng ñoái töôïng                                                                              

 

 

 

13 

• 

ñaït ñöôïc tính ña daïng thôøi gian bieân dòch. 

 
Ví duï 1.7     

Cuøng soá ñoái soá.  
Trình bieân dòch seõ choïn phieân baûn thích hôïp cuûa haøm ñeå goïi.  

 
#include <iostream.h> 
 
// Overload abs() three ways 
int abs(int n) 
long abs(long n) 
 
double abs(double n) 
 
int main() 

  cout << "Absolute value of -10: " << abs(-10) << "\n\n"; 
  cout << "Absolute value of -10L: " << abs(-10L) << "\n\n"; 
  cout << "Absolute value of -10.01: " << abs(-10.01) << "\n\n"; 
 
  return 0; 

 
// abs() for ints 
int abs(int n) 

  cout << "In integer abs()\n"; 
  return n<0 ? -n : n; 

 
// abs() for longs 
long abs(long n) 

  cout << "In long abs()\n"; 
  return n<0 ? -n : n; 

// abs() for doubles 
double abs(double n) 

background image

Chöông 1    Toång quan veà Laäp trình höôùng ñoái töôïng                                                                              

 

 

 

14 


  cout << "In double abs()\n"; 
  return n<0 ? -n : n; 

 
 
Ví duï 1.8 

Khaùc soá ñoái soá vaø khaùc kieåu döõ lieäu 

 
#include <iostream.h> 
 
void date(char *date);    

 

// date as a string 

void date(int month, int day, int year);  

// date as numbers 

 
int main() 

  date("8/23/99"); 
  date(8, 23, 99); 
 
  return 0; 

 
// Date as string. 
void date(char *date) 

  cout << "Date: " << date << "\n"; 

 
 
// Date as integers. 
void date(int month, int day, int year) 

  cout << "Date: " << month << "/"; 
  cout << day << "/" << year << "\n"; 

 
Ví duï 1.9 

Hai haøm chæ khaùc nhau ôû kieåu döõ lieäu traû veà laøm cho trình bieân dòch  
khoâng theå löïa choïn kieåu ñuùng ñeå goïi. 

background image

Chöông 1    Toång quan veà Laäp trình höôùng ñoái töôïng                                                                              

 

 

 

15 

 
// This is incorrect and will not compile. 
int f1(int a); 
double f1(int a); 
 
int main() 

  f1(10);  

// which function does the compiler call??? 

  return 0; 

 



 
 
 
4/ Caùc töø khoaù (keywords) trong C++ 
 
Ngoaøi caùc töø khoaùduøng trong ngoân ngöõ  C, ANSI C++ söû duïng caùc töø khoaù thöôøng 
duøng nhö sau : 
 
asm 

 delete 

 new 

 protected 

throw 

 ... 

 

bool 

 false 

 operator 

public 

 true 

 ... 

 

catch 

 friend 

 overload 

template 

try 

 ... 

 

class 

 inline 

 private  this 

 virtual 

 ... 

 

 

 
YÙ nghiaõ cuûa chuùng seõ ñöôïc laàn löôït giaûi thích vaø minh hoaï trong caùc chöông sau cuûa 
baøi giaûng. 
 

 

background image

 

 

 
Chöông 2   

 

Lôùp, ñoái töôïng vaø tính ñoùng goùi 

 
 
 
 
 
 

 

• 

Lôùp  

 

• 

Haøm taïo, haøm huûy  

 

• 

Tham soá cuûa haøm taïo  

 

• 

Noäi tuyeán töï ñoäng  

 

• 

Gaùn ñoái töôïng 

 

• 

Truyeàn caùc ñoái töôïng sang haøm 

 

• 

Traû ñoái töôïng töø haøm 

 

• 

Haøm friend 

 
 
 
 
 
 
 
 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

17 

17

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

18 

18

I/ Lôùp (class) 

• 

Cuù phaùp khai baùo lôùp 

 
class

  class_name { 

   private : 
 

// khai baùo caùc bieán ; 
// khai baùo caùc haøm;  

   public : 
 

// khai baùo caùc bieán ; 
// khai baùo caùc haøm;  

}

 objects_list ; 

 
class_name   teân cuûa lôùp do ngöôøi duøng ñònh nghiaõ. 
objects_list   danh saùch caùc ñoái töôïng, coù theå tuøy choïn. 
 
Caùc bieán, caùc haøm khai baùo beân trong moät lôùp goïi laø caùc thaønh vieân cuûa lôùp ñoù. 
 
Töø khoaù 

YÙ nghiaõ 

class 

khai baùo moät lôùp 

private : 

qui ñònh caùc bieán, caùc haøm laø caùc thaønh vieân rieâng cuûa lôùp, beân 
ngoaøi lôùp khoâng theå truy caäp ñöôïc. 

public : 
 

qui ñònh caùc bieán, caùc haøm laø caùc thaønh vieân chung cuûa lôùp, coù 
theå truy caäp chuùng töø caùc thaønh vieân khaùc cuûa lôùp vaø bôûi caùc 
thaønh phaàn khaùc cuûa chöông trình coù chöùa lôùp ñoù. 

 
 

• 

Cuù phaùp ñònh nghiaõ haøm thaønh vieân 

 
data_type  class_name :: func_name (arg_list) 

 

// body of function 


 
 
data_type    kieåu döõ lieäu cuûa phöông thöùc traû veà 
class_name  teân lôùp chöùa haøm 
::

  

 

toaùn töû phaân giaûi phaïm vi (scope resolution operator) 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

19 

19

func_name   teân haøm 
arg_list 

danh saùch caùc ñoái soá 

 
 
Ví duï 1.1

 

Khai baùo lôùp coù teân  "myclass" 

 
class

 myclass { 

  // private to myclass 
  int a; 
public: 
  void set_a(int num); 
  int get_a(); 
}; 
 
void myclass::set_a(int num)

  // ñònh nghiaõ haøm void set_a(int num) 


  a = num; 

 
int myclass::get_a()

 

 

 

// ñònh nghiaõ haøm int get_a() 


  return a; 

 
int main() 

  myclass  ob1, ob2;  

// khai baùo 2 ñoái töôïng coù teân  ob1, ob2 

 
  ob1.set_a(10); 

 

// thieát laäp giaù trò 10 cho baûn sao cuaû bieán a cuûa ob1  

  ob2.set_a(99); 

 

// thieát laäp giaù trò 99 cho baûn sao cuaû bieán a cuûa ob2 

 
  cout << ob1.get_a() << "\n"; 
  cout << ob2.get_a() << "\n"; 
  return 0; 

 
 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

20 

20

Ví duï 1.2

 

Loãi bieân dòch khi truy caäp ñeán bieán rieâng a töø beân ngoaøi lôùp myclass 

 
int main() 

  myclass ob1, ob2; 
 
  ob1.a = 10;   

// ERROR!  cannot access private member 

  ob2.a = 99;   

//                     by non-member functions. 

  return 0; 

 
Ví duï 1.3

 

Khi a laø bieán chung, coù theå  truy caäp a töø beân ngoaøi lôùp myclass 

#include <iostream.h> 
 
class myclass { 
public: 
  // now a is public 
  int a; 
  // and there is no need for set_a() or get_a() 
}; 
 
int main() 

  myclass ob1, ob2; 
 
  // here, a is accessed directly 
  ob1.a = 10; 
  ob2.a = 99; 
 
  cout << ob1.a << "\n"; 
  cout << ob2.a << "\n"; 
 
  return 0; 

 
 
 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

21 

21

Ví duï 1.4

 

Taïo lôùp stack duøng ñeå chöùa caùc kyù töï 

 
#include <iostream.h> 
#define SIZE 10 
// Declare a stack class for characters 
class stack {  
  char stck[SIZE];   // holds the stack 
  int tos;  

 

// index of top-of-stack 

public: 
  void init();    

// initialize stack 

  void push(char ch);  

// push character on stack 

  char pop();   

// pop character from stack 

}; 
 
// Initialize the stack 
void stack::init() 

  tos = 0; 

 
// Push a character. 
void stack::push(char ch) 

  if(tos == SIZE) { 
    cout << "Stack is full"; 
    return; 
  } 
  stck[tos] = ch; 
  tos++; 

 
// Pop a character. 
char stack::pop() 

  if(tos == 0) { 
    cout << "Stack is empty"; 
    return 0; // return null on empty stack  

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

22 

22

  } 
  tos--; 
  return stck[tos]; 

 
int main() 

  stack s1, s2;  // create two stacks 
  int i; 
 
  // initialize the stacks 
  s1.init(); 
  s2.init(); 
 
  s1.push('a'); 
  s2.push('x'); 
  s1.push('b'); 
  s2.push('y'); 
  s1.push('c'); 
  s2.push('z'); 
 
  for(i=0; i<3; i++) cout << "Pop s1: " << s1.pop() << "\n"; 
  for(i=0; i<3; i++) cout << "Pop s2: " << s2.pop() << "\n"; 
 
  return 0; 

 
 
@ Keát quaû xuaát döõ lieäu cuûa chöông trình ? 
 
 

• 

Löu yù  

Khai baùo lôùp laø moät tröøu töôïng logic ñeå ñònh nghiaõ moät kieåu döõ lieäu môùi. 
 
Khai baùo moät ñoái töôïng döïa vaøo lôùp, taïo ra moät thöïc theå vaät lyù (coù ñiaï chæ trong boä 
nhôù) coù kieåu döõ lieäu ñoù. 
 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

23 

23

Moãi ñoái töôïng cuûa moät lôùp coù baûn sao rieâng cuûa caùc bieán ñöôïc khai baùo trong lôùp. 
 

 

Baøi taäp I 
 

 

1. Haõy taïo lôùp card ñeå giöõ caùc muïc nhaäp catalog theû thö vieän, chöaù töïa ñeà saùch (kieåu 
chuoãi), teân taùc giaû (kieåu chuoãi) vaø soá baûn (kieåu nguyeân). Duøng haøm thaønh vieân 
chung store() ñeå löu tröõ thoâng tin veà saùch vaø haøm thaønh vieân chung show() ñeå hieån 
thò thoâng tin. Vieát chöông trình thöïc hieän yeâu caàu treân. 
 
2. Taïo lôùp haøng ñôïi (queue) ñeå giöõ haøng caùc soá nguyeân. Taïo moät kích thöôùc haøng 
daøi 100 soá nguyeân. Vieát chöông trình thöïc hieän yeâu caàu treân. 

 
 
II/ Haøm taïo & haøm huûy  

 

1/ Khaùi nieäm  
Haøm taïo

 (constructor) coù cuøng teân vôùi lôùp, laø haøm thaønh phaàn cuûa moät lôùp,  

khoâng coù kieåu traû veà. 
 
Muïc ñích cuûa haøm taïo nhaèm taïo ra caùc khôûi ñaàu cho moät ñoái töôïng.  
Haøm taïo ñöôïc goïi töï ñoäng moãi khi ñoái töôïng cuûa lôùp ñoù ñöôïc taïo ra. 
 
2/ Khai baùo 
 
class  class_name { 
 

// khai baùo caùc bieán vaø haøm ; 

   public : 
 

// khai baùo caùc bieán vaø haøm ; 
class_name()

 ; 

 

// khai baùo haøm taïo  

} objects_list ; 
 
 
Ví duï 2.1

 

Lôùp myclass  coù haøm taïo myclass() vaø haøm show() 

#include <iostream.h> 
 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

24 

24

class myclass { 
  int a; 
public: 
  myclass() ;   

// constructor  

  void show(); 
}; 
 
myclass::myclass()  // ñònh nghiaõ haøm taïo  

  cout << "In constructor\n"; 
  a = 10; 

 
void myclass::show() 

  cout << a; 

 
int main() 

  myclass ob;       // haøm taïo myclass() ñöôïc goïi töï ñoäng khi ñoái töôïng ob ñöôïc taïo ra  
  ob.show(); 
  return 0; 

 
Ñoái vôùi caùc ñoái töôïng chung, moät haøm taïo cuûa ñoái töôïng ñöôïc goïi moät laàn khi 
chöông trình baét ñaàu thi haønh laàn ñaàu. 
 
Ñoái vôùi caùc ñoái töôïng rieâng, haøm taïo cuûa ñoái töôïng ñöôïc goïi moãi khi leänh khai baùo 
ñöôïc thi haønh. 
 
3/ Khaùi nieäm haøm huûy (destructor) 
Haøm huûy

 coù cuøng teân vôùi lôùp, coù keøm theo daáu ~ ñöùng tröôùc, laø haøm thaønh phaàn cuûa 

moät lôùp, khoâng coù kieåu traû veà. 
 
Muïc ñích cuûa haøm huûy nhaèm thi haønh moät soá taùc ñoäng khi ñoái töôïng bò huûy boû, 
chaúng haïn moät ñoái töôïng yeâu caàu caáp phaùt boä nhôù khi ñoái töôïng ñöôïc taïo ra vaø giaûi 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

25 

25

phoùng boä nhôù khi ñoái töôïng bò huûy boû.  
 
Haøm huûy ñöôïc goïi töï ñoäng moãi khi ñoái töôïng cuûa lôùp ñoù bò huûy boû. 
 
4/ Khai baùo 
class  class_name { 
 

// khai baùo caùc bieán vaø haøm ; 

   public : 
 

// khai baùo caùc bieán vaø haøm ; 
class_name(); 

 

 

 

// khai baùo haøm taïo   

~class_name()

 

 

// khai baùo haøm huûy  

} objects_list ; 
 
 
Ví duï 2.2

 

Lôùp myclass  coù haøm taïo myclass() vaø haøm huûy ~myclass() 

#include <iostream.h> 
 
class myclass { 
  int a; 
public: 
  myclass();    

// constructor  

  ~myclass();  

 

// destructor  

  void show(); 
}; 
 
myclass::myclass() 

  cout << "In constructor\n"; 
  a = 10; 

 
myclass::~myclass() 

  cout << "Destructing...\n"; 

 
 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

26 

26

void myclass::show() 

  cout << a << "\n"; 

 
int main() 

  myclass ob; 
  ob.show(); 
  return 0; 

 
 
Ñoái vôùi caùc ñoái töôïng chung, haøm huûy cuûa ñoái töôïng ñöôïc goïi khi chöông trình keát 
thuùc. 
 
Ñoái vôùi caùc ñoái töôïng rieâng, haøm huûy cuûa ñoái töôïng ñöôïc goïi khi chuùng ra khoûi phaïm 
vi. 
 

• 

Löu yù

 : Khoâng theå bieát ñöôïc ñòa chæ cuûa haøm taïo hoaëc haøm huûy.  

 
Ví duï 2.3

    Duøng haøm taïo stack() ñeå töï ñoäng khôûi ñaàu ngaên xeáp khi ñoái töôïng ñöôïc 

taïo  
 
#include <iostream.h> 
#define SIZE 10 
// Declare a stack class for characters. 
class stack {  
  char stck[SIZE];   // holds the stack 
  int tos;  

 

// index of top-of-stack 

public: 
  stack();  

 

// constructor 

  void push(char ch);  

// push character on stack 

  char pop();   

// pop character from stack 

}; 
 
// Initialize the stack. 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

27 

27

stack::stack() 

  cout << "Constructing a stack\n"; 
  tos = 0; 

 
// Push a character. 
void stack::push(char ch) 

  if(tos==SIZE) { 
    cout << "Stack is full\n"; 
    return; 
  } 
  stck[tos] = ch; 
  tos++; 

 
// Pop a character. 
char stack::pop() 

  if(tos==0) { 
    cout << "Stack is empty\n"; 
    return 0;    

// return null on empty stack  

  } 
  tos--; 
  return stck[tos]; 

 
int main() 

  // Create two stacks that are automatically initialized. 
  stack s1, s2;  
  int i; 
 
  s1.push('a'); 
  s2.push('x'); 
  s1.push('b'); 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

28 

28

  s2.push('y'); 
  s1.push('c'); 
  s2.push('z'); 
 
  for(i=0; i<3; i++) cout << "Pop s1: " << s1.pop() << "\n"; 
  for(i=0; i<3; i++) cout << "Pop s2: " << s2.pop() << "\n"; 
 
  return 0; 

 
 
Ví duï 2.4 

   Duøng haøm taïo strtype() vaø haøm huûy ~strtype() ñeå töï ñoäng caáp phaùt  

boä nhôù cho chuoåi *p vaø giaûi phoùng boä nhôù khi ñoái töôïng bò huûy. 

 
#include <iostream.h> 
#include <string.h> 
#include <stdlib.h> 
#include <malloc.h> 
 
#define SIZE 255 
 
class strtype { 
  char *p; 
  int len; 
public: 
  strtype();   // constructor 
  ~strtype();   //destructor 
  void set(char *ptr); 
  void show(); 
}; 
 
// Initialize a string object. 
strtype::strtype() 

  p = (char *) malloc(SIZE); 
  if(!p) { 
    cout << "Allocation error\n"; 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

29 

29

    exit(1); 
  } 
  *p = '\0'; 
  len = 0; 

 
// Free memory when destroying string object. 
strtype::~strtype() 

  cout << "Freeing p\n"; 
  free(p); 

 
void strtype::set(char *ptr) 

  if(strlen(ptr) >= SIZE) { 
    cout << "String too big\n"; 
    return; 
  } 
  strcpy(p, ptr); 
  len = strlen(p); 

 
void strtype::show() 

  cout << p << " - length: " << len; 
  cout << "\n"; 

 
int main() 

  strtype s1, s2; 
 
  s1.set("This is a test."); 
  s2.set("I like C++."); 
 
  s1.show(); 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

30 

30

  s2.show(); 
 
  return 0; 

 
 
Ví duï 2.5

     Duøng ñoái töôïng cuûa lôùp timer ñeå xaùc ñònh khoaûng thôøi gian  

khi moät ñoái töôïng kieåu timer ñöôïc taïo vaø cho ñeán khi bò huûy. 

 
#include <iostream.h> 
#include <ctime.h> 
 
class timer { 
  clock_t start; 
public: 
  timer(); // constructor 
  ~timer(); // destructor 
}; 
 
timer::timer() 

  start = clock(); 

 
timer::~timer() 

  clock_t end; 
 
  end = clock(); 
  cout << "Elapsed time: " << (end-start) / CLOCKS_PER_SEC << "\n"; 

 
int main() 

  timer  ob; 
  char c; 
 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

31 

31

  // delay ... 
  cout << "Press a key followed by ENTER: "; 
  cin >> c; 
 
  return 0; 

 
Chöông trình naøy duøng haøm thö vieän chuaån clock() ñeå traû veà soá chu kyø ñoàng hoà xaûy 
ra töø khi chöông trình baét ñaàu chaïy. Chia giaù trò naøy cho haèng soá CLK-TCK ñeå 
chuyeån thaønh giaù trò giaây. (CLK-TCK ñònh nghiaõ soá tic-taéc cuûa ñoàng hoà trong moät 
giaây) 

 
 
Baøi taäp II 

 

1. Thöïc hieän laïi lôùp queue trong baøi taäp I/ 2. chöông 2 ñeå thay haøm khôûi ñaàu baèng 
haøm taïo. 
 
2. Taïo lôùp stopwatch ñeå so vôùi ñoàng hoà baám giôø trong vieäc xaùc ñònh thôøi gian troâi 
qua, ñöôïc tính baèng giaây. Caùc yeâu caàu : 
- Lôùp stopwatch coù 2 bieán rieâng start vaø end löu soá giaây 
- Vieát haøm taïo ñeå ñaït thôøi gian troâi qua luùc ñaàu veà zero.  
- Hai haøm thaønh vieân start() vaø stop() ñeå laàn löôït môû vaø taét cheá ñoä ñònh giôø.  
- Haøm thaønh vieân show() ñeå hieån thò thôøi gian troâi qua.  
- Vieát haøm huûy ñeå töï ñoäng hieån thò thôøi gian troâi qua khi ñoái töôïng stopwatch bò huûy. 
 
3. Söûa loãi trong ñoaïn chöông trình sau : 
 

class sample { 

 

 

double a, b, c; 

 public 

  double 

sample() 

   

 
 
 
 

III/ Tham soá cuûa haøm taïo  

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

32 

32

 
1/ Khaùi nieäm  
Haøm taïo coù theå coù caùc tham soá, chæ caàn boå sung caùc tham soá thích hôïp trong khai baùo 
lôùp vaø trong ñònh nghóa haøm taïo.  
 
Khi khai baùo moät ñoái töôïng, caàn chæ roõ caùc tham soá naøy laøm ñoái soá. 
 
Ví duï 3.1

   Haøm taïo myclass(int x) coù moät tham soá 

#include <iostream.h> 
 
class myclass { 
  int a; 
public: 
  myclass(int x);   // constructor 
  void show(); 
}; 
myclass::myclass(int x) 

  cout << "In constructor\n"; 
  a = x; 

 
void myclass::show() 

  cout << a << "\n"; 

 
int main() 

  myclass ob(4)
  ob.show(); 
  return 0; 

 
Giaù trò 4 trong khai baùo ñoái töôïng ob(4), laø ñoái soá ñöôïc truyeàn cho tham soá x cuûa 
haøm taïo myclass(int x), duøng ñeå khôûi taïo bieán a. 
Caùch vieát khaùc (daøi hôn)    

myclass ob = myclass (4) ; 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

33 

33

• 

Löu yù haøm huûy khoâng coù tham soá. Do khoâng coù cô cheá naøo ñeå truyeàn ñoái soá cho 

moät ñoái töôïng bò huûy. 

 
 
Ví duï 3.2

   Coù theå truyeàn nhieàu tham soá cho haøm taïo  

 
#include <iostream.h> 
class myclass { 
  int a, b; 
public: 
  myclass(int x, int y);  

// constructor 

  void show(); 
}; 
 
myclass::myclass(int x, int y) 

  cout << "In constructor\n"; 
  a = x; 
  b = y; 

 
void myclass::show() 

  cout << a << ' ' << b << "\n"; 

 
int main() 

  myclass  ob(4, 7); 
  ob.show(); 
  return 0; 

 
 
 
 
Ví duï 3.3 

  Duøng haøm taïo ñöôïc tham soá hoùa ñeå truyeàn "teân" cho stack.  

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

34 

34

 
#include <iostream.h> 
#define SIZE 10 
// Declare a stack class for characters. 
class stack {  
  char stck[SIZE];    

// holds the stack 

  int tos;  

 

 

// index of top-of-stack 

  char who;    

 

// identifies stack 

public: 
  stack(char c);  

 

// constructor 

  void push(char ch);  

 

// push character on stack 

  char pop();   

 

// pop character from stack 

}; 
 
// Initialize the stack. 
stack::stack(char c) 

  tos = 0; 
  who = c; 
  cout << "Constructing stack " << who << "\n"; 

 
// Push a character. 
void stack::push(char ch) 

  if(tos == SIZE) { 
    cout << "Stack " << who << " is full\n"; 
    return; 
  } 
  stck[tos] = ch; 
  tos++; 

 
// Pop a character. 
char stack::pop() 

  if(tos == 0) { 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

35 

35

    cout << "Stack " << who << " is empty\n"; 
    return 0; // return null on empty stack  
  } 
  tos--; 
  return stck[tos]; 

 
int main() 

  // Create two stacks that are automatically initialized. 
  stack s1('A'), s2('B');  
  int i; 
 
  s1.push('a'); 
  s2.push('x'); 
  s1.push('b'); 
  s2.push('y'); 
  s1.push('c'); 
  s2.push('z'); 
 
  // This will generate some error messages. 
  for(i=0; i<5; i++) cout << "Pop s1: " << s1.pop() << "\n"; 
  for(i=0; i<5; i++) cout << "Pop s2: " << s2.pop() << "\n"; 
  return 0; 

 
 
@ Muïc ñích :  duøng ñeå nhaän ra teân stack naøo ñöôïc tham chieáu khi coù loãi xaûy ra.  
     Ñieàu naøy raát coù ích trong quaù trình gôõ roái (debug). 
 
 
Ví duï 3.4

   Ñoái soá cuûa haøm taïo laø moät chuoåi.  

 
#include <iostream.h> 
#include <string.h> 
#include <stdlib.h> 
#include <malloc.h> 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

36 

36

 
class  strtype { 
  char  *p; 
  int  len; 
public: 
  strtype(char *ptr); 
  ~strtype(); 
  void show(); 
}; 
 
strtype::strtype(char *ptr) 

  len = strlen(ptr); 
  p = (char *) malloc(len+1); 
  if(!p) { 
    cout << "Allocation error\n"; 
    exit(1); 
  } 
  strcpy(p, ptr); 

 
strtype::~strtype() 

  cout << "Freeing p\n"; 
  free(p); 

 
void strtype::show() 

  cout << p << " - length: " << len; 
  cout << "\n"; 

 
int main() 

  strtype s1("This is a test.") , s2("I like C++.") ; 
  s1.show(); 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

37 

37

  s2.show(); 
  return 0; 

 
Ví duï 3.6

   Coù theå truyeàn cho haøm taïo cuûa ñoái töôïng moät bieåu thöùc hoaëc caùc bieán.  

#include <iostream.h> 
 
class myclass { 
  int i, j; 
public: 
  myclass(int a, int b); 
  void show(); 
}; 
 
myclass::myclass(int a, int b) 

  i = a; 
  j = b; 

 
void myclass::show() 

  cout << i << ' ' << j << "\n"; 

 
int main() 

  int x, y; 
 
  cout << "Enter two integers: "; 
  cin >> x >> y; 
 
  // use variables to construct ob 
  myclass  ob(x, y); 
  ob.show(); 
  return 0;} 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

38 

38

Baøi taäp III 

 
 

1. Vieát chöông trình thay ñoåi lôùp stack ñeå cho noù caáp phaùt boä nhôù ñoäng cho ngaên xeáp 
chöùa caùc kyù töï. Kích thöôùc ngaên xeáp ñöôïc chæ roõ baèng moät tham soá vôùi haøm taïo. 
Haøm huûy giaûi phoùng boä nhôù ñoäng. 
 
2. Haõy taïo lôùp t_and_d ñeå truyeàn ngaøy vaø giôø heä thoáng hieän haønh nhö moät tham soá 
cho haøm taïo cuûa noù khi ñöôïc taïo ra. Lôùp goàm coù haøm thaønh vieân hieån thò ngaøy giôø 
naøy leân maøn hình. Duøng caùc haøm ngaøy vaø giôø chuaån trong thö vieän chuaån ñeå tìm vaø 
hieän thò ngaøy. 
 
3. Vieát chöông trình taïo lôùp box coù haøm taïo ñöôïc truyeàn 3 giaù trò double, dieãn taû ñoä 
daøi caùc caïnh cuûa hoäp. Haõy cho lôùp box tính theå tích cuûa hình laäp phöông vaø löu tröõ 
keát quûa trong bieán double. Taïo haøm thaønh vieân vol() ñeå hieån thò theå tích cuûa moãi ñoái 
töôïng box. 

 

 
 
IV/ Noäi tuyeán töï ñoäng (in-line) 

 

1/ Khaùi nieäm 
Khi ñònh nghiaõ haøm thaønh phaàn laø ñuû ngaén thì coù theå ñaët ñònh nghiaõ trong khai baùo 
haøm trong lôùp ñoù. Haøm naøy seõ ñöôïc goïi laø haøm noäi tuyeán (in-line func.) vaø khoâng 
caàn duøng töø khoaù inline ñöùng tröôùc haøm ñoù. 
 
Ví duï 4.1 
#include <iostream.h> 
 
class samp { 
  int  i, j; 
public: 
  samp(int a, int b); 
 
  // divisible() is defined here and automatically  in-lined 
  int divisible()  { return !(i%j) ; } 
}; 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

39 

39

samp::samp(int a, int b) 

  i = a; 
  j = b; 

 
int main() 

  samp ob1(10, 2), ob2(10, 3); 
 
  // this is true 
  if(ob1.divisible())  cout << "10 divisible by 2\n"; 
 
  // this is false 
  if(ob2.divisible())  cout << "10 divisible by 3\n"; 
 
  return 0; 

 
Ví duï 4.2

 

Duøng haøm noäi tuyeán ñeå ñònh nghiaõ caùc haøm taïo vaø haøm huûy 

#include <iostream.h> 
 
class samp { 
  int i, j; 
public: 
  samp(int a, int b) { i = a; j = b; } 

 

// inline constructor 

  int divisible() { return !(i%j); } 
}; 
 
 
Ví duï 4.3

 

Moät haøm ngaén ôû beân trong moät khai baùo lôùp  
cho duø ñaëc ñieåm noäi tuyeán töï ñoäng laø khoâng coù giaù trò. 

 
class myclass { 
  int i; 
public: 
  myclass(int n) { i = n; } 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

40 

40

  void show() { cout << i; } 
}; 
 
 
Baøi taäp IV 
 
 
1. Vieát chöông trình chuyeån ñoåi lôùp stack trong ví duï 2.3 chöông 2, ñeå lôùp naøy söû 
duïng caùc haøm noäi tuyeán töï ñoäng ôû nhöõng nôi thích hôïp. 
 
2. Vieát chöông trình chuyeån ñoåi lôùp strtype trong ví duï 2.4 chöông 2, ñeå lôùp naøy söû 
duïng caùc haøm noäi tuyeán töï ñoäng. 
 
 

V/ Gaùn ñoái töôïng 

 

1/ Khaùi nieäm 
Moät ñoái töôïng ñöôïc gaùn cho moät ñoái töôïng khaùc ñeå caû hai ñoái töôïng coù cuøng kieåu, 
khi ñoù söï sao cheùp töøng bit cuûa caùc thaønh vieân döõ lieäu ñöôïc thöïc hieän
 
Ví duï 5.1 
// An example of object  assignment. 
#include <iostream.h> 
 
class myclass { 
  int a, b; 
public: 
  void set(int i, int j) { a = i; b = j; } 
  void show() { cout << a << ' ' << b << "\n"; } 
}; 
 
int main() 

  myclass o1, o2; 
  o1.set(10, 4); 
 
  // assign o1 to o2 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

41 

41

  o2 = o1
 
  o1.show(); 
  o2.show(); 
  return 0; 

 
Neáu boå sung caùc doøng leänh sau ñaây vaøo tröôùc doøng return 0; , keát quaû seõ ra sao ? 

o1.set(3, 2); 
o1.show(); 
o2.show(); 

 
 
2/ Caùc tính chaát 
a/ Leänh gaùn ñoái töôïng chæ aùp duïng cho caùc ñoái töôïng coù cuøng kieåu (veà maët vaät lyù) vaø 
cuøng teân kieåu

 
Ví duï 5.2 
// This program has  an error. 
#include <iostream.h> 
 
class myclass { 
  int a, b; 
public: 
  void set(int i, int j) { a = i; b = j; } 
  void show() { cout << a << ' ' << b << "\n"; } 
}; 
 
/* This class is similar to myclass but uses a different class name and thus appears 
as  
a different type to the compiler   */ 
class yourclass { 
  int a, b; 
public: 
  void set(int i, int j) { a = i; b = j; } 
  void show() { cout << a << ' ' << b << "\n"; } 
}; 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

42 

42

int main() 

  myclass o1; 
  yourclass o2; 
 
  o1.set(10, 4); 
  o2 = o1;    

// ERROR, objects  not  of  same type name 

 
  o1.show(); 
  o2.show(); 
  return 0; 

 
b/ Pheùp gaùn ñoái töôïng coøn aùp duïng cho caùc döõ lieäu phöùc taïp nhö maûng, ... 
 
Ví duï 5.3 
#include <iostream.h> 
 
#define SIZE 10 
 
// Declare a stack class for characters. 
class stack {  
  char stck[SIZE];   // holds the stack 
  int tos;  

 

// index of top-of-stack 

public: 
  stack();  

 

// constructor 

  void push(char ch);  

// push character on stack 

  char pop();   

// pop character from stack 

}; 
 
// Initialize the stack. 
stack::stack() 

  cout << "Constructing a stack\n"; 
  tos = 0; 

 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

43 

43

// Push a character. 
void stack::push(char ch) 

  if(tos==SIZE) { 
    cout << "Stack is full\n"; 
    return; 
  } 
  stck[tos] = ch; 
  tos++; 

 
// Pop a character. 
char stack::pop() 

  if(tos==0) { 
    cout << "Stack is empty\n"; 
    return 0; // return null on empty stack  
  } 
  tos--; 
  return stck[tos]; 

 
int main() 

  // Create two stacks that are automatically initialized. 
  stack s1, s2;  
  int i; 
 
  s1.push('a'); 
  s1.push('b'); 
  s1.push('c'); 
 
  // clone s1 
  s2 = s1;    // now s1 and s2 are identical 
 
  for(i=0; i<3; i++) cout << "Pop s1: " << s1.pop() << "\n"; 
  for(i=0; i<3; i++) cout << "Pop s2: " << s2.pop() << "\n"; 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

44 

44

  return 0; 

 
 
c/ Ñoái vôùi caùc ñoái töôïng coù söû duïng chuoåi, khi thöïc hieän pheùp gaùn ñoái töôïng phaûi 
chaéc chaén raèng khoâng huûy boû caùc thoâng tin caàn thieát trong ñoái töôïng ñoù. 
 
Ví duï 5.4 
// This program contains an error. 
 
#include <iostream.h> 
#include <string.h> 
#include <stdlib.h> 
#include <malloc.h> 
 
class strtype { 
  char *p; 
  int len; 
public: 
  strtype(char *ptr); 
  ~strtype(); 
  void show(); 
}; 
strtype::strtype(char *ptr) 

  len = strlen(ptr); 
  p = (char *) malloc(len+1); 
  if(!p) { 
    cout << "Allocation error\n"; 
    exit(1); 
  } 
  strcpy(p, ptr); 

 
strtype::~strtype() 

  cout << "Freeing p\n"; 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

45 

45

  free(p); 

 
void strtype::show() 

  cout << p << " - length: " << len; 
  cout << "\n"; 

 
int main() 

  strtype s1("This is a test."), s2("I like C++."); 
 
  s1.show(); 
  s2.show(); 
 
  // assign s1 to s2 - - this generates an error 
  s2 = s1; 
 
  s1.show(); 
  s2.show(); 
  return 0; 

Nguyeân nhaân naøo gaây ra loãi ? 
 
Baøi taäp V 
 
 
1. Tìm loãi sai trong ñoaïn chöông trình sau 
#include <iostream> 
class cl1 { 
  int i, j; 
public: 
  cl1(int a, int b) { i = a; j = b; } 
  // ... 
}; 
class cl2 { 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

46 

46

  int i, j; 
public: 
  cl2(int a, int b) { i = a; j = b; } 
  // ... 
}; 
 
int main() 

  cl1  x(10, 20); 
  cl2  y(0, 0); 
  x = y; 
 
  // ... 

 
2. Vieát chöông trình döïa vaøo lôùp queue trong baøi taäp II/ 1. chöông II  chöùng toû moät 
haøng ñôïi coù theå ñöôïc gaùn cho moät haøng ñôïi khaùc. 
 
3. Neáu lôùp queue trong caâu 2. caáp phaùt boä nhôù ñoäng ñeå giöõ haøng ñôïi, taïi sao trong 
tröôøng hôïp naøy, moät haøng ñôïi khoâng theå ñöôïc gaùn cho haøng ñôïi khaùc. 
 
 

VI/ Truyeàn caùc ñoái töôïng sang haøm 

 
1/ Vieäc truyeàn caùc ñoái töôïng cho haøm gioáng nhö truyeàn caùc ñoái soá thoâng thöôøng. 
Tham soá cuûa haøm coù kieåu döõ lieäu laø kieåu lôùp, vaø ñoái soá truyeàn cho haøm chính laø ñoái 
töôïng

 
Gioáng nhö caùc kieåu döõ lieäu khaùc, theo ngaàm ñònh, taát caû caùc ñoái töôïng ñöôïc truyeàn 
bôûi giaù trò cho moät haøm. 
 
Ví duï 6.1 

  Truyeàn moät ñoái töôïng cho haøm. 

#include <iostream.h> 
 
class samp { 
  int i; 
public: 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

47 

47

  samp(int n) { i = n; } 
  int get_i() { return i; } 
}; 
 
// Return square of o.i. 
int sqr_it(samp o

  return o.get_i() * o.get_i(); 

 
int main() 

  samp a(10), b(2); 
 
  cout << sqr_it(a) << "\n"; 
  cout << sqr_it(b) << "\n"; 
 
  return 0; 

 
2/ Do ñoái töôïng ñöôïc truyeàn bôûi giaù trò cho moät haøm, coù nghóa laø vieäc sao cheùp töøng 
bit cuûa ñoái soá ñöôïc thöïc hieän vaø chính sao cheùp naøy ñöôïc söû duïng bôûi haøm. Do ñoù, 
nhöõng thay ñoåi cho ñoái töôïng beân trong haøm khoâng coù aûnh höôûng ñeán söï goïi ñoái 
töôïng. 
 
Ví duï 6.2 

 

#include <iostream.h> 
 
class samp { 
  int i; 
public: 
  samp(int n) { i = n; } 
  void set_i(int n) { i = n; } 
  int get_i() { return i; } 
}; 
 
// Set o.i  to its square. This has no effect on the object used to call sqr_it(), 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

48 

48

however. 
void sqr_it(samp o

   o.set_i( o.get_i() * o.get_i() ) ; 
 
  cout << "Copy of a has  i  value of  " << o.get_i(); 
  cout << "\n"; 

 
int main() 

  samp a(10); 
 
  sqr_it(a) ;    

// a passed by value, displays 100 

 
  cout << "But, a.i  is unchanged in main: "; 
  cout << a.get_i();   // displays 10 
  return 0; 

 
 
3/ Khi truyeàn ñiaï chæ cuûa ñoái töôïng sang haøm (seõ khoâng taïo ra baûn sao ñoái töôïng), 
noäi dung cuûa ñoái töôïng seõ bò thay ñoåi. 
 
Ví duï 6.3 
#include <iostream.h> 
class samp { 
  int i; 
public: 
  samp(int n) { i = n; } 
  void set_i(int n) { i = n; } 
  int get_i() { return i; } 
}; 
 
/*  Set o.i to its square. This affects the calling argument. */ 
void sqr_it(samp *o

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

49 

49

   o->set_i(o->get_i() * o->get_i()); 
 
  cout << "Copy of a has i value of " << o->get_i(); 
  cout << "\n"; 

 
int main() 

  samp a(10); 
  sqr_it(&a);   

// pass a's address to sqr_it(), displays 100 

 
  cout << "Now, a in main() has been changed: "; 
  cout << a.get_i();   // displays 100 
  return 0; 

 
 
4/ Baûn sao cuûa ñoái töôïng 
Khi truyeàn moät ñoái töôïng cho haøm,  moät baûn sao cuûa ñoái töôïng ñöôïc thöïc hieän, coù 
nghóa laø moät ñoái töôïng môùi xuaát hieän. Do ñoù khi haøm keát thuùc laøm vieäc, baûn sao cuûa 
ñoái töôïng ñoù (ñoái soá cuûa haøm) seõ bò huûy. 
 
Ñieàu naøy laøm naûy sinh hai vaán ñeà :  
- Haøm taïo cuûa ñoái töôïng ñöôïc goïi khi baûn sao thöïc hieän ? 
- Haøm huûy cuûa ñoái töôïng ñöôïc goïi khi baûn sao bò huûy ? 
Khi baûn sao cuûa moät ñoái töôïng ñöôïc thöïc hieän ñeå duøng goïi haøm, thì haøm taïo khoâng 
ñöôïc goïi

. Do haøm taïo thöôøng ñöôïc duøng ñeå khôûi ñaàu moät khiaù caïnh naøo ñoù cuûa ñoái 

töôïng. Khi truyeàn moät ñoái töôïng cho moät haøm, baïn caàn ñeán traïng thaùi hieän haønh cuûa 
ñoái töôïng chöù khoâng phaûi traïng thaùi ban ñaàu.  
 
Khi haøm keát thuùc vaø baûn sao bò huûy, haøm huûy ñöôïc goïi.  
 
Ví duï 6.4 
 
#include <iostream.h> 
class samp { 
  int i; 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

50 

50

public: 
  samp(int n) {  
    i = n;  
    cout << "Constructing\n"; 
  } 
  ~samp() { cout << "Destructing\n"; } 
  int get_i() { return i; } 
}; 
 
// Return square of o.i. 
int sqr_it(samp o

  return o.get_i() * o.get_i(); 

 
int main() 

  samp a(10); 
 
  cout << sqr_it(a) << "\n"; 
   return 0; 

 
Noäi dung chöông trình thöïc hieän 
 Constructing 
 Destructing 
 100 
 Destructing 
 
Giaûi thích ? 
 
 
Haøm huûy cuûa baûn sao ñoái töôïng 

ñöôïc goïi khi haøm keát thuùc coù theå laø nguyeân nhaân cuûa 

nhieàu vaán ñeà.  
 
Chaúng haïn, neáu ñoái töôïng coù haøm taïo caáp phaùt boä nhôù ñoäng hoaëc haøm huûy giaûi 
phoùng boä nhôù ñoäng, thì baûn sao cuûa ñoái töôïng seõ giaûi phoùng boä nhôù ñoäng khi haøm 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

51 

51

huûy cuûa noù ñöôïc goïi. Ñieàu naøy laøm cho ñoái töôïng goác bò hoûng vaø trôû thaønh voâ duïng. 
 
Ví duï 6.5 
// This program contains an error. 
#include <iostream.h> 
#include <stdlib.h> 
 
class dyna { 
  int *p; 
public: 
  dyna(int i); 
  ~dyna() { free(p); cout << "freeing \n"; } 
  int get() { return *p; } 
}; 
 
dyna::dyna(int i) 

  p = (int *) malloc(sizeof(int)); 
  if(!p) { 
    cout << "Allocation failure\n"; 
    exit(1); 
  } 
 
  *p = i; 

 
// Return negative value of *ob.p 
int neg(dyna ob)   

  return -ob.get(); 

 
int main() 

  dyna o(-10); 
 
  cout << o.get() << "\n";  // -10 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

52 

52

  cout << neg(o) << "\n";  // freeing 
 

 

 

 

// 10 

  dyna o2(20); 
  cout << o2.get() << "\n";  // 20 
  cout << neg(o2) << "\n";  // freeing 
 

 

 

 

// -20 

  cout << o.get() << "\n";  // 20  do *p ñöôïc caáp ñòa chæ vuøng nhôù ñoäng 
  cout << neg(o) << "\n";  // freeing 
 

 

 

 

// -20 

  return 0;   

 

// freeing o 

    // 

freeing 

o2 

 

 

 

 

// Null pointer assignment  


 
Giaûi thích nguyeân nhaân gaây loåi ? 
 
 

• 

Coù theå khaéc phuïc baèng caùch truyeàn ñiaï chæ cuûa ñoái töôïng cho haøm. Vì seõ khoâng 

coù ñoái töôïng môùi ñöôïc taïo ra vaø khoâng coù haøm huûy cuûa baûn sao ñoái töôïng ñöôïc 
goïi khi haøm traû veà. 

 
Tuy nhieân, giaûi phaùp toát nhaát laø söû duïng haøm taïo baûn sao (copy constructor), cho 
pheùp ñònh nghiaõ caùch thöùc taïo caùc baûn sao cuûa caùc ñoái töôïng (xem chöông sau). 
 
Baøi taäp VI 
 
1.  Vieát chöông trình taïo lôùp stack trong ví duï 5.3 chöông 2, boå sung haøm 
showstack() ñeå truyeàn moät ñoái töôïng kieåu stack. Cho haøm naøy hieån thò noäi dung cuûa 
ngaên xeáp. 
 
2. Tìm loãi sai trong chöông trình naøy 
#include <iostream.h> 
#include <stdlib.h> 
 
class dyna { 
  int *p; 
public: 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

53 

53

  dyna(int i); 
  ~dyna() { free(p);   cout << "freeing \n"; } 
  int get() { return *p; } 
}; 
 
dyna::dyna(int i) 

  p = (int *) malloc(sizeof(int)); 
  if(!p) { 
    cout << "Allocation failure\n"; 
    exit(1); 
  } 
 
  *p = i; 

 
// Return negative value of *ob.p 
int neg(dyna ob)   

  return -ob.get(); 

 
int main() 

  dyna o(-10); 
 
  cout << o.get() << "\n"; 
  cout << neg(o) << "\n"; 
 
  dyna o2(20); 
  cout << o2.get() << "\n"; 
  cout << neg(o2) << "\n"; 
 
  cout << o.get() << "\n"; 
  cout << neg(o) << "\n"; 
 
  return 0; 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

54 

54

 
 

VII/ Traû ñoái töôïng töø haøm 

 

• 

Ñoái töôïng traû veà töø haøm thoâng qua caâu leänh return. Khi ñoù moät ñoái töôïng taïm 

ñöôïc töï ñoäng taïo ra ñeå giöõ giaù trò traû veà.  

 
Chính ñoái töôïng naøy thöïc söï ñöôïc traû veà bôûi haøm. Sau khi giaù trò ñöôïc traû veà, ñoái 
töôïng naøy bò huûy, söï huûy ñoái töôïng taïm coù theå gaây ra taùc duïng ngoaøi yù muoán. 
 
Ví duï 7.1 
// Returning an object 
#include <iostream.h> 
#include <string.h> 
 
class samp { 
  char s[80]; 
public: 
  void show() { cout << s << "\n"; } 
  void set(char *str) { strcpy(s, str); }  
}; 
 
// Return an object of type samp 
samp input() 

  char s[80]; 
  samp str; 
 
  cout << "Enter a string: "; 
  cin >> s; 
 
  str.set(s); 
  return str; 

 
 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

55 

55

int main() 

  samp ob; 
 
  // assign returned object to ob 
  ob = input()

 

 

// Enter a string:  Hello  

 

 

 

ob.show(); 

   // 

Hello 

  return 0; 

 
Ví duï 7.2 

Phaûi thaän troïng khi haøm traû veà ñoái töôïng, khi ñoái töôïng naøy coù chöùa  
haøm huûy. 

 
// An error generated by returning an object. 
#include <iostream.h> 
#include <string.h> 
#include <stdlib.h> 
 
class samp { 
  char *s; 
public: 
  samp() { s = '\0'; } 
  ~samp() { if(s)   free(s);  cout << "Freeing s\n"; } 
  void show() { cout << s << "\n"; } 
  void set(char *str); 
}; 
 
// Load a string. 
void samp::set(char *str) 

  s = (char *) malloc(strlen(str)+1); 
  if(!s) { 
    cout << "Allocation error\n"; 
    exit(1); 
  } 
  strcpy(s, str); 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

56 

56

// Return an object of type samp. 
samp input() 

  char s[80]; 
  samp str; 
 
  cout << "Enter a string: "; 
  cin >> s; 
 
  str.set(s); 
  return str; 

 
int main() 

  samp ob; 
 
  // assign returned object to ob 
  ob = input();  // This causes an error!!!! 
  ob.show(); 
 
  return 0; 

 
Haõy giaûi thích keát quaû cuûa chöông trình ? 
 

Enter a astring: Hello 

 Freeing 

 Freeing 

 Hello 
 Freeing 

 

Null  pointer  assignment 

 
Khi moät ñoái töôïng ñöôïc traû veà töø moät haøm, moät ñoái töôïng taïm ñöôïc duøng ñeå thöïc 
hieän söï traû veà seõ laøm huûy boä nhôù (ñöôïc caáp phaùt cho chuoåi s) cuûa ñoái töôïng ñöôïc goïi. 
Ñeå traùnh tình traïng naøy coù theå söû duïng haøm taïo baûn sao. 
 
 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

57 

57

Baøi taäp VII 
 
1.  Vieát chöông trình taïo lôùp Who, cho haøm taïo cuûa Who nhaän moät ñoái soá  kyù töï maø 
ñoái soá  naøy ñöôïc duøng ñeå nhaän daïng moät ñoái töôïng.  
 
Haõy cho haøm taïo hieån thò moät thoâng baùo töông töï thoâng baùo sau ñaây khi taïo ra moät 
ñoái töôïng : 

 

Constructing who #x 

Trong ñoù x laø kyù töï nhaän daïng. 
 
Haõy taïo haøm make_who() ñeå traû veà ñoái töôïng Who. Haõy cho moãi ñoái töôïng moät teân 
duy nhaát. 
 

 

VIII/ Caùc haøm friend 
 

• 

Moät haøm friend khoâng phaûi laø haøm thaønh vieân cuûa lôùp nhöng coù theå truy caäp 

caùc thaønh vieân rieâng

 cuûa lôùp. 

 
Moät haøm friend ñöôïc ñònh nghiaõ nhö moät haøm bình thöôøng. Neáu naèm beân trong 
moät lôùp

, haøm friend seõ coù töø khoaù friend ñöùng tröôùc. 

 
Haøm friend khoâng ñöôïc keá thöøa töø lôùp daãn xuaát (xem chöông 6). 
 

• 

Caùc lôïi ích khi duøng haøm friend : 

  

+ söï quaù taûi toaùn töû (xem chöông 5).  

 

+ taïo ra caùc kieåu haøm nhaäp/xuaát naøo ñoù (xem chöông 8). 

 

+ taïo haøm ñeå truy caäp caùc thaønh vieân rieâng cuûa hai hay nhieàu lôùp khaùc nhau. 

 
Ví duï 8.1 
 
// A example of a friend function. 
#include <iostream.h> 
 
class myclass { 
  int n, d; 
public: 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

58 

58

  myclass(int i, int j) { n = i; d = j; } 
  // declare a friend of myclass 
  friend  int  isfactor(myclass ob) ;    
}; 
 
/*  Here is friend function definition. It returns true if d is a factor of n. Notice that 
the keyword friend is not used in the definition of isfactor().  */ 
int  isfactor(myclass ob) 

  if(!(ob.n % ob.d)) return 1; 
  else return 0; 

 
int main() 

  myclass ob1(10, 2), ob2(13, 3); 
 
  if( isfactor(ob1) )   cout << "2 is a factor of 10\n"; 
  else  cout << "2 is not a factor of 10\n"; 
 
  if( isfactor(ob2) )   cout << "3 is a factor of 13\n"; 
  else  cout << "3 is not a factor of 13\n"; 
 
  return 0; 

 
 

• 

Khoâng theå goïi haøm friend baèng caùch duøng teân ñoái töôïng vaø toaùn töû truy caäp 

thaønh vieân (daáu chaám hoaëc muõi teân)  

 

ob1.isfactor();  

// wrong,  isfactor()  is not a member function 

 

• 

Khoâng gioáng nhö caùc haøm thaønh vieân cuûa lôùp, coù theå tham chieáu tröïc tieáp ñeán 

caùc bieán (rieâng hoaëc chung) cuûa lôùp ñoù, moät haøm friend chæ coù theå truy caäp caùc 
bieán naøy khi lieân keát vôùi moät ñoái töôïng ñöôïc khai baùo trong hoaëc ñöôïc truyeàn ñeán 
cho haøm friend

.  

 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

59 

59

• 

Moät haøm friend coù theå laø caùc haøm friend cuûa hôn moät lôùp. 

 
Ví duï 8.2

 

#include <iostream.h> 
 
class truck;   // a forward declaration 
 
class car { 
  int passengers; 
  int speed; 
public: 
  car(int p, int s) { passengers = p; speed = s; } 
  friend int sp_greater(car c, truck t); 
}; 
 
class truck { 
  int weight; 
  int speed; 
public: 
  truck(int w, int s) { weight = w, speed = s; } 
  friend int sp_greater(car c, truck t); 
}; 
 
/* Return positive   if car speed faster than truck. 
    Return 0     

if speeds are the same. 

    Return negative   if truck speed faster than car. 

*/ 

int sp_greater(car c, truck t) 

  return c.speed - t.speed; 

 
int main() 

  int t; 
  car c1(6, 55), c2(2, 120); 
  truck t1(10000, 55), t2(20000, 72); 
 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

60 

60

  cout << "Comparing c1 and t1:\n"; 
  t = sp_greater(c1, t1);   
  if(t < 0)  

cout << "Truck is faster.\n"; 

  else  if(t == 0)  

cout << "Car and truck speed is the same.\n"; 

  else cout << "Car is faster.\n"; 
 
  cout << "\nComparing c2 and t2:\n"; 
  t = sp_greater(c2, t2); 
  if(t < 0)  

cout << "Truck is faster.\n"; 

  else  if(t == 0)  

cout << "Car and truck speed is the same.\n"; 

else  cout << "Car is faster.\n"; 

  return 0; 

 
Söï tham chieáu tôùi (forward reference) laø ñieàu caàn thieát cho trình bieân dòch, do haøm 
sp_greater() nhaän caùc tham soá cuûa caû hai lôùp car vaø truck. 
 

• 

Moät haøm coù theå laø thaønh vieân cuûa moät lôùp vaø laø moät haøm friend cuûa lôùp khaùc . 

 
Ví duï 8.3 
#include <iostream.h> 
 
class truck

;  // a forward declaration 

 
class car { 
  int passengers; 
  int speed; 
public: 
  car(int p, int s) { passengers = p; speed = s; } 
  int sp_greater(truck t)
}; 
 
class truck { 
  int weight; 
  int speed; 
public: 
  truck(int w, int s) { weight = w, speed = s; } 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

61 

61

 
  // note new use of the scope resolution operator 
  friend int car::sp_greater(truck t)
}; 
/* Return positive   if car speed faster than truck. 
    Return 0    

if speeds are the same. 

    Return negative   if truck speed faster than car. */ 
int car::sp_greater(truck t) 

   // Since sp_greater() is member of car, only a truck object must be passed to it. 
    return speed - t.speed; 

 
int main() 

  int t; 
  car  c1(6, 55), c2(2, 120); 
  truck  t1(10000, 55), t2(20000, 72); 
 
  cout << "Comparing c1 and t1:\n"; 
  t = c1.sp_greater(t1);    // evoke as member function of car 
 
  if(t<0)  

cout << "Truck is faster.\n"; 

  else if(t==0)  

cout << "Car and truck speed is the same.\n"; 

   

else cout << "Car is faster.\n"; 

 
  cout << "\nComparing c2 and t2:\n"; 
  t = c2.sp_greater(t2);   // evoke as member function of car 
 
  if(t<0) 

 cout << "Truck is faster.\n"; 

  else if(t==0)  

cout << "Car and truck speed is the same.\n"; 

else cout << "Car is faster.\n"; 

 
  return 0; 

 
Caâu leänh     

 

t = c1.sp_greater(t1); 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

62 

62

coù theå vieát ñaày ñuû (ít duøng) 

t = c1.car::sp_greater(t1); 

 
 
 
 
Baøi taäp VIII 
 
 
1. Coù 2 lôùp pr1 vaø pr2 ñang duøng chung moät maùy in. Chöông trình caàn bieát khi naøo 
thì maùy in ñöôïc duøng bôûi ñoái töôïng naøo thuoäc moät trong hai lôùp ñoù. Haõy taïo haøm 
inuse() traû veà giaù trò ñuùng khi maùy in ñang ñöôïc duøng vaø giaù trò sai khi ngöôïc laïi. 
Laøm cho haøm naøy trôû thaønh haøm friend cuûa caû hai lôùp pr1 vaø pr2. 
 
class pr1 { 
  int printing; 
  // ... 
public: 
  pr1() { printing = 0; } 
  void set_print(int status) { printing = status; } 
  // ... 
}; 
 
class pr2 { 
  int printing; 
  // ... 
public: 
  pr2() { printing = 0; } 
  void set_print(int status) { printing = status; } 
  // ... 
}; 
 
 
 
 
 
 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

63 

63

Baøi taäp chöông 2 

 
 

1. Ñeå moät ñoái töôïng ñöôïc gaùn vaøo moät ñoái töôïng khaùc, caàn coù ñieàu kieän gì ? 
class samp { 
  double *p; 
public: 
  samp(double d) {  
    p = (double *) malloc(sizeof(double)); 
    if(!p) exit(1);  // allocation error 
    *p = d; 
  } 
  ~samp() { free(p); } 
  // ... 
}; 
 
// ... 
samp ob1(123.09), ob2(0.0); 
// ... 
ob2 = ob1; 
 
Vaán ñeà gì sinh ra do pheùp gaùn ob1 vaøo ob2 ? 
 
2. Cho lôùp planet, haõy taïo haøm light() nhaän moät ñoái töôïng kieåu planet laøm ñoái soá traû 
veà moät soá giaây caàn thieát ñeå aùnh saùng ñi töø maët trôøi ñeán haønh tinh. (Giaû söû aùnh saùng 
di chuyeån vôùi vaän toác 186.000 miles/second vaø dist_from_sun tính baèng miles) 
 
class planet { 
  int moons; 
  double dist_from_sun;  // in miles 
  double diameter; 
  double mass; 
public: 
  //... 
  double get_miles() { return dist_from_sun; }     
}; 
 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

64 

64

3. Duøng lôùp stack, haõy vieát haøm loadstack() ñeå traû veà moät ngaên xeáp ñaõ ñöôïc naïp vaøo 
caùc maãu töï alphabet (a-z). Haõy gaùn ngaên xeáp naøy cho moät ñoái töôïng khaùc khi goïi 
moät chöông trình phuï vaø chöùng toû raèng noù chöùa caùc maãu töï alphabet. 
 
4. Haõy taïo lôùp line ñeå veõ moät ñöôøng treân maøn hình. Löu tröõ ñoä daøi cuûa ñöôøng trong 
moät bieán nguyeân rieâng len. Haõy cho haøm taïo löu tröõ ñoä daøi vaø veõ ñöôøng baèng caùch 
duøng daáu "*". Laäp haøm huûy cuûa line ñeå xoaù ñöôøng. 
 
5. Haõy söûa ñoåi chöông trình sau ñaây ñeå cho moïi haøm thaønh vieân ñöôïc töï ñoäng noäi 
truyeán. 
 
class myclass  { 
  int i, j; 
public: 
  myclass(int x, int y); 
  void show(); 
}; 
 
myclass::myclass(int x, int y) 
{  
  i = x;  
  j = y; 

 
void myclass::show() 

  cout << i << " " << j << "\n"; 

 
int main() 

  myclass  count(2, 3);  count.show(); 
  return 0; 

 
 
 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

65 

65

6. Haõy taïo lôùp prompt, truyeàn haøm taïo cuûa lôùp naøy moät chuoåi, ví duï "Nhaäp vaøo moät 
soá nguyeân : ". Cho haøm taïo hieån thò chuoåi vaø sau ñoù nhaän vaøo moät soá nguyeân. Löu 
tröõ giaù trò naøy trong moät bieán rieâng cuûa lôùp goïi laø count. Khi ñoái töôïng coù kieåu 
prompt bò huûy, cho chuoâng reng  count laàn. 
 
7. Vieát chöông trình taïo moät lôùp change thöïc hieän vieäc chuyeån ñoåi inch thaønh cm. 
Lôùp change coù hai bieán rieâng löu tröõ soá inch vaø giaù trò töông ñöông cuûa noù baèng cm. 
Haõy truyeàn cho haøm taïo soá inch vaø hieån thò soá cm. Bieát 1 inch = 2,54 cm 
 
8. Cho lôùp sau, vieát chöông trình chöùng toû ñoái töôïng ob ñöôïc khai baùo ñeå truyeàn giaù 
trò 100 cho bieán a vaø "z" cho bieán c. 
class sample { 
 

int  a; 

 

char  c; 

public : 
 

sample(int x, char  c) { a = x; c = ch;} 

 // 

... 

}; 
 
9. Döïa vaøo baøi taäp 3 chöông 2, vieát chöông trình thöïc hieän haøm quaù taûi loadstack() 
nhaän moät soá nguyeân goïi laø upper, laøm ñoái soá. Trong phieân baûn quaù taûi, neáu upper = 
1, haõy ñöa vaøo ngaên xeáp caùc kyù töï in hoa. Ngöôïc laïi, ñöa vaøo ngaên xeáp caùc kyù töï 
thöôøng. 
 
 
10. Duøng lôùp strtype trong ví duï 5.4 chöông 2, haõy boå sung moät haøm friend, coù teân 
get_string(), nhaän con troû veà moät ñoái töôïng kieåu strtype laøm tham soá vaø traû veà con 
troû cho moät chuoåi ñöôïc troû bôûi ñoái töôïng ñoù. 
 
 
11. Cho lôùp sau, haõy taïo haøm make_sum() ñeå traû veà moät ñoái töôïng kieåu summation. 
Haõy laøm cho haøm naøy nhaéc ngöôì duøng nhaäp moät soá vaø sau ñoù taïo moät ñoái töôïng 
nhaän giaù trò naøy vaø traû noù veà cho thuû tuïc. Vieát chöông trình thöïc hieän yeâu caàu treân. 
 
 
12. Trong baøi taäp 11 treân, haøm set_sum() ñaõ khoâng ñöôïc ñònh nghiaõ noäi tuyeán töï 
ñoäng trong khai baùo lôùp summation. Haõy giaûi thích taïi sao ? 

background image

Chöông 2    Lôùp, Ñoái töôïng vaø tính ñoùng goùi                                                                             

 

 

 

66 

66

13. Cho lôùp sau ñaây, haõy boå sung moät haøm friend isneg() nhaän moät tham soá loaïi 
myclass vaø traû veà giaù trò ñuùng neáu num laø aâm vaø giaù trò sai neáu ngöôïc laïi. 
 
class  myclass { 
 int 

num; 

public : 
 

myclass(int x) { num = x;} 

}; 
 
 
14. Moät haøm friend coù theå laø nhöõng haøm friend cuûa nhieàu hôn moät lôùp ñöôïc khoâng ? 

background image

 

 

 

Chöông 3   
 

Maûng , Con troû vaø Tham chieáu 

 
 
 

 
 
 
 
 

• 

Maûng caùc ñoái töôïng 

 

• 

Con troû ñoái töôïng 

 

• 

Con troû this 

 

• 

Toaùn töû new vaø delete 

 

• 

Tham chieáu (reference) 

 

• 

Truyeàn tham chieáu cho ñoái töôïng 

 

• 

Traû veà caùc tham chieáu 

 

• 

Caùc tham chieáu ñoäc laäp vaø caùc haïn cheá 

 
 
 
 
 
 
 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

68

68 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

69

69 

I/ Maûng caùc ñoái töôïng 

Caùc ñoái töôïng chính laø caùc bieán , coù caùc khaû naêng vaø thuoäc tính nhö caùc bieán thoâng 
thöôøng khaùc. Do ñoù, caùc ñoái töôïng coù theå toå chöùc thaønh maûng. 
 
Cuù phaùp khai baùo moät maûng caùc ñoái töôïng hoaøn toaøn gioáng nhö ngoân ngöõ C. 
Vieäc truy caäp maûng caùc ñoái töôïng cuõng gioáng nhö maûng cuûa caùc loaïi bieán khaùc. 
 
Ví duï 1.1 

Maûng caùc ñoái töôïng 

#include <iostream.h> 
 
class samp { 
  int a; 
public: 
  void set_a(int n) { a = n; } 
  int get_a() { return a; } 
}; 
 
int main() 

  samp ob[4]

;      // 

khai 

baùo 

maûng 

ñoái 

töôïng 

  int i; 
 
  for(i=0; i<4; i++)   ob[i].set_a(i); 

 

 

// truy caäp maûng ñoái töôïng 

  for(i=0; i<4; i++)   cout << ob[i].get_a( ); 
  return 0; 

 
 

• 

Neáu kieåu lôùp coù haøm taïo, thì maûng ñoái töôïng coù theå ñöôïc khôûi ñaàu

 
Ví duï 1.2 
// Initialize an array. 
#include <iostream.h> 
class samp { 
  int a; 
public: 
  samp(int n) { a = n; } 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

70

70 

  int get_a() { return a; } 
}; 
 
int main() 

  samp ob[4] = { -1, -2, -3, -4 }
  int i; 
 
  for(i=0; i<4; i++)   cout << ob[i].get_a() << ' '; 
  return 0; 

 
@ Moät caùch vieát khaùc (daøi hôn)  

samp ob[4] = { samp(-1), samp(- 2), samp(-3), samp(- 4) }; 
 

@ Caùch khôûi ñaàu ôû treân chæ laøm vieäc vôùi caùc maûng coù haøm taïo chæ nhaän moät ñoái soá.  
 
 

• 

Khôûi ñaàu maûng ñoái töôïng nhieàu chieàu. 

 
Ví duï 1.3 
// Create a two-dimensional array of objects. 
#include <iostream.h> 
 
class samp { 
  int a; 
public: 
  samp(int n) { a = n; } 
  int get_a() { return a; } 
}; 
 
int main() 

  samp ob[4][2] = { 1, 2, 

3, 4, 
5, 6, 
7, 8  };

 

  int i; 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

71

71 

    for(i=0; i<4; i++) { 
    cout << ob[i][0].get_a() << ' '; 
    cout << ob[i][1].get_a() << "\n"; 
  } 
  return 0; 

 

• 

Khi khôûi ñaàu moät maûng ñoái töôïng coù haøm taïo nhaän nhieàu ñoái soá , caàn phaûi duøng 

daïng khôûi ñaàu khaùc. 

 
Víduï 1.4 
#include <iostream.h> 
 
class samp { 
  int a, b; 
public: 
  samp(int n, int m) { a = n; b = m; } 
  int get_a() { return a; } 
  int get_b() { return b; } 
}; 
 
int main() 

  samp ob[4][2] = { samp(1, 2),    samp(3, 4),  

samp(5, 6),    samp(7, 8), 
samp(9, 10),   samp(11, 12), 
samp(13, 14), samp(15, 16)  } 

  int i; 
 
  for(i=0; i<4; i++) { 
    cout << ob[i][0].get_a() << ' '; 
    cout << ob[i][0].get_b() << "\n"; 
    cout << ob[i][1].get_a() << ' '; 
    cout << ob[i][1].get_b() << "\n"; 
  } 
  return 0; 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

72

72 

 
Baøi taäp I 
 
1. Duøng khai baùo lôùp sau ñaây ñeå taïo maûng 10 phaàn töû vaø khôûi ñaàu phaàn töû ch vôùi caùc 
giaù trò töø A ñeán J. Haõy chöùng toû maûng chöùa caùc giaù trò naøy. 
#include <iostream.h> 
 
class letters { 
  char ch; 
public: 
  letters(char c) { ch = c; } 
  char get_ch() { return ch; } 
}; 
 
2. Duøng khai baùo lôùp sau ñaây ñeå taïo maûng 10 phaàn töû vaø khôûi ñaàu num vôùi caùc giaù 
trò töø 1 ñeán 10 vaø haõy khôûi ñaàu spr ñoái vôùi bình phöông cuûa num. 
 
#include <iostream.h> 
 
class squares { 
  int num, sqr; 
public: 
  squares(int a, int b) { num = a; sqr = b; } 
  void show() {cout << num << ' ' << sqr << "\n"; } 
}; 

 
 
II/ Con troû ñoái töôïng 

Caùc ñoái töôïng coù theå ñöôïc truy caäp thoâng qua con troû, toaùn töû -> seõ ñöôïc duøng. 
 
Khai baùo moät con troû ñoái töôïng

 gioáng nhö khai baùo moät con troû höôùng veà kieåu bieán 

baát kyø. Ví duï  

samp *p; 

 
Ñeå coù ñiaï chæ cuûa moät ñoái töôïng, duøng toaùn töû & ñaët tröôùc ñoái töôïng. Ví duï 
  p 

&ob; 

 
 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

73

73 

Ví duï 2.1 
#include <iostream.h> 
 
class myclass { 
  int a; 
public: 
  myclass(int x);   // constructor 
  int get(); 
}; 
 
myclass::myclass(int x) 

  a = x; 

 
int myclass::get() 

  return a; 

 
int main() 

  myclass ob(120);   // create object 
  myclass *p;   

// create pointer to object 

 
  p = &ob;    

// put address of ob into p 

 
  cout << "Value using object: " << ob.get() << "\n" ; 
  cout << "Value using pointer: " << p->get()
 
  return 0; 

 
 
@ Vieäc taïo ra moät con troû ñoái töôïng khoâng taïo ra moät ñoái töôïng, noù chæ taïo ra moät 
con troû troû veà ñoái töôïng. 
 
 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

74

74 

• 

Soá hoïc con troû : 

+ Khi taêng con troû ñoái töôïng, noù seõ troû ñeán ñoái töôïng tieáp theo. 
+ Khi giaûm con troû ñoái töôïng, noù seõ troû ñeán ñoái töôïng ñöùng tröôùc. 

 
 
Ví duï 2.2  
// Pointers to objects. 
#include <iostream.h> 
 
class samp { 
  int a, b; 
public: 
  samp(int n, int m) { a = n; b = m; } 
  int get_a() { return a; } 
  int get_b() { return b; } 
}; 
 
int main() 

  samp ob[4] = { 
    samp(1, 2),  
    samp(3, 4),  
    samp(5, 6),  
    samp(7, 8) 
  };  
  int i; 
 
  samp *p; 
  p = ob ;  

// get starting address of array 

 
  for(i=0; i<4; i++) { 
    cout << p->get_a() << ' '; 
    cout << p->get_b() << "\n"; 
    p++;   

// advance to next object 

  } 
 
   return 0; 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

75

75 

 
Baøi taäp II 
 
 
1. Haõy vieát laïi ví duï 2.2 chöông 3 ñeå cho noù hieån thò noäi dung cuûa maûng ob theo thöù 
töï ngöôïc laïi. 
 
2. Haõy vieát laïi ví duï 1.3 chöông 3 ñeå truy caäp maûng hai chieàu qua con troû. 
 
 

III/ Con troû this 

this

 laø con troû ñöôïc truyeàn töï ñoäng cho baát kyø haøm thaønh vieân naøo khi ñöôïc goïi vaø 

noù laø con troû tôùi ñoái töôïng taïo ra lôøi goïi haøm. 
 
Ví duï, cho caâu leänh ob.f1() ;  

// ob laø ñoái töôïng  

 
Haøm f1() töï ñoäng ñöôïc truyeàn con troû ob laø ñoái töôïng taïo ra lôøi goïi haøm. Con troû naøy 
ñöôïc xem laø this . 
 
Chæ coù caùc haøm thaønh vieân ñöôïc truyeàn con troû this. Haøm friend khoâng coù con troû 
this

Con troû this coù nhieàu söû duïng, keå caû vieäc giuùp quaù taûi caùc toaùn töû. 
 

• 

Khi moät haøm thaønh vieân tham chieáu moät haøm thaønh vieân khaùc cuûa lôùp, noù thöïc 

hieän maø khoâng xaùc ñònh tham chieáu vôùi hoaëc moät lôùp hoaëc moät ñaëc taû ñoái töôïng

 
Ví duï 3.1 
// Demonstrate the this pointer. 
#include <iostream.h> 
#include <string.h> 
 
class inventory { 
  char item[20]; 
  double cost; 
  int on_hand; 
public: 
  inventory(char *i, double c, int o) 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

76

76 

  { 

 

     // tham chieáu tröïc tieáp caùc bieán  item[], cost, on_hand 
     strcpy(item, i);   

 

     cost = c; 
     on_hand = o; 
   } 
   void show(); 
}; 
 
void inventory::show() 

  cout << item; 
  cout << ": $" << cost; 
  cout << "  On hand: " << on_hand << "\n"; 

 
int main() 

  inventory ob("wrench", 4.95, 4); 
 
  ob.show(); 
  return 0; 

 
 

• 

Khi moät haøm thaønh vieân ñöôïc goïi, noù töï ñoäng ñöôïc truyeàn con troû this troû veà ñoái 

töôïng taïo ra lôøi goïi

. Chöông trình coù theå vieát laïi : 

 
Ví duï 3.2 
#include <iostream.h> 
#include <string.h> 
 
class inventory {   

// Demonstrate the this pointer. 

  char item[20]; 
  double cost; 
  int on_hand; 
public: 
  inventory(char *i, double c, int o) 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

77

77 

  { 
     strcpy(this->item, i);   // access members 
     this->cost = c;     

// through the this 

     this->on_hand = o;  

// pointer 

   } 
   void show(); 
}; 
 
void inventory::show() 

  cout << this->item; // use this to access members 
  cout << ": $" << this->cost; 
  cout << "  On hand: " << this->on_hand << "\n"; 

int main() 

  inventory ob("wrench", 4.95, 4); 
 
  ob.show(); 
  return 0; 

 
 
Baøi taäp III 
 
Haõy chuyeån taát caû caùc tham chieáu thích hôïp ñoái vôùi caùc thaønh vieân cuûa lôùp thaønh 
tham chieáu con troû this. 
#include <iostream.h> 
 
class myclass { 
  int a, b; 
public:  
  myclass(int n, int m) { a = n; b = m; } 
  int add() { return a+b; } 
  void show(); 
}; 
 
void myclass::show() 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

78

78 


  int t; 
 
  t = add();   // call member function 
  cout << t << "\n"; 

 
int main() 

  myclass ob(10, 14); 
 
  ob.show(); 
  return 0; 

 
 

IV/ Toaùn töû new vaø delete 

 
1/ Toaùn töû new duøng ñeå caáp phaùt boä nhôù ñoäng vaø toaùn töû delete duøng giaûi phoùng boä 
nhôù ñaõ caáp phaùt. 
 
Cuù phaùp 

p_var = new  data_type; 

 

 

delete

 p_var; 

 

 

data_type

 

chæ ñònh kieåu ñoái töôïng muoán caáp phaùt boä nhôù 

p_var

   

con troû tôùi kieåu ñoù 

 
 
Gioáng nhö haøm malloc(), neáu khoâng ñuû boä nhôù theo yeâu caàu caáp phaùt thì toaùn töû 
new seõ traû veà con troû NULL. Toaùn töû delete ñöôïc goïi chæ vôùi moät con troû ñaõ ñöôïc 
caáp phaùt tröôùc ñoù qua toaùn töû new. Neáu goïi delete vôùi moät con troû khoâng hôïp leä, heä 
thoáng caáp phaùt seõ bò huûy, vaø coù theå laøm hoûng chöông trình. 
 
Caùc öu ñieåm  
  + toaùn töû new töï ñoäng caáp phaùt boä nhôù ñeå giöõ moät ñoái töôïng coù kieåu ñöôïc chæ roõ. 
  + toaùn töû new töï ñoäng traû veà moät con troû coù kieåu ñöôïc chæ roõ. 
  + toaùn töû new vaø delete coù theå ñöôïc quaù taûi. 
  + coù theå khôûi ñaàu ñoái töôïng ñöôïc caáp phaùt ñoäng. 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

79

79 

  + khoâng caàn naïp thö vieän malloc.h hoaëc stdlib.h vaøo trong chöông trình. 
 
 

• 

Caáp phaùt boä nhôù ñoäng ñeå giöõa moät soá nguyeân 

 
Ví duï 4.1 
// A simple example of new and delete. 
#include <iostream.h> 
 
int main() 

  int *p; 
 
  p = new int ;  

// allocate room for an integer 

  if(!p) {  
    cout << "Allocation error\n"; 
    return 1; 
  } 
 
  *p = 1000; 
 
  cout << "Here is integer at p: " << *p << "\n"; 
 
  delete p;     

// release memory 

  return 0; 

 
 

• 

Caáp phaùt ñoäng moät ñoái töôïng  

 
Ví duï 4.2 
// Allocating dynamic objects. 
#include <iostream.h> 
 
class samp { 
  int i, j; 
public: 
  void set_ij(int a, int b) { i=a; j=b; } 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

80

80 

  int get_product() { return i*j; } 
}; 
 
int main() 

  samp *p; 
 
  p = new samp ;   // allocate object 
  if(!p) { 
    cout << "Allocation error\n"; 
    return 1; 
  } 
 
  p->set_ij(4, 5); 
 
  cout << "Product is: " << p->get_product() << "\n"; 
  
  delete p

;     

// release memory 

  return 0; 

 
 
Baøi taäp IVa 
 
1. Haõy vieát chöông trình söû duïng new ñeå caáp phaùt ñoäng moät float, moät long vaø moät 
char. Cho caùc bieán ñoäng naøy nhöõng giaù trò vaø hieån thò. Sau ñoù, haõy duøng delete giaûi 
phoùng taát caû boä nhôù. 
 
2. Haõy taïo moät lôùp coù chöùa teân vaø soá ñieän thoaïi cuûa moät ngöôøi. Duøng new ñeå caáp 
phaùt ñoäng moät ñoái töôïng cuûa lôùp naøy, löu teân vaø soá ñieän thoaïi vaøo ñoái töôïng ñoù roài 
hieån thò. 
 
 
 
2/ Caùc ñaëc ñieåm cuûa new vaø delete 

+ caùc ñoái töôïng ñöôïc caáp phaùt ñoäng moät giaù trò ñaàu 
   

p_var = new data_type(initial_value)

 ; 

  

 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

81

81 

+ caùc maûng ñöôïc caáp phaùt ñoäng coù theå ñöôïc taïo ra 

p_var = new data_type[size]

 ; 

 
p_var troû tôùi ñaàu maûng coù phaàn töû size coù kieåu ñöôïc chæ roõ.  
Vì lyù do kyõ thuaät, khoâng theå khôûi ñaàu moät maûng ñaõ ñöôïc caáp phaùt ñoäng. 
 

        + ñeå huûy boû maûng ñaõ ñöôïc caáp phaùt ñoäng 

delete [] p_var

 ; 

 
 

p_var seõ ñöôïc giaûi phoùng moät laàn. 

 
 

• 

caáp phaùt boä nhôù cho moät soá nguyeân vaø khôûi ñaàu boä nhôù ñoù 

 
 
Ví duï 4.3 
// An example of initializing a dynamic variable. 
 
#include <iostream.h> 
 
int main() 

  int *p; 
 
  p = new int(9) ;   // give initial value of 9 
 
 
  if(!p) { 
    cout << "Allocation error\n"; 
    return 1; 
  } 
 
  cout << "Here is integer at p: " << *p << "\n"; 
 
  delete p;  // release memory 
  return 0; 

• 

truyeàn caùc giaù trò ñaàu cho moät ñoái töôïng ñöôïc caáp phaùt ñoäng 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

82

82 

 
Ví duï 4.4 
// Allocating dynamic objects. 
#include <iostream.h> 
 
class samp { 
  int i, j; 
public: 
  samp(int a, int b) { i=a; j=b; } 
  int get_product() { return i*j; } 
}; 
 
int main() 

  samp *p; 
 
  p = new samp(6, 5);  

// allocate object with initialization 

  if(!p) { 
    cout << "Allocation error\n"; 
    return 1; 
  } 
 
  cout << "Product is: " << p->get_product() << "\n"; 
 
  delete p; 
  return 0; 

 
 

• 

Caáp phaùt moät maûng soá nguyeân 

 
Ví duï 4.5 
// A simple example of new and delete. 
#include <iostream.h> 
 
int main() 

  int *p; 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

83

83 

 
  p = new int [5];   // allocate room for 5 integers 
 
  // always make sure that allocation succeeded 
  if(!p) { 
    cout << "Allocation error\n"; 
    return 1; 
  } 
 
  int i; 
 
  for(i=0; i<5; i++)   p[i] = i; 
 
  for(i=0; i<5; i++) { 
    cout << "Here is integer at p[" << i << "]: "; 
    cout << p[i] << "\n"; 
  } 
 
  delete [] p;   

// release memory 

 
  return 0; 

 
 

• 

Taïo moät maûng ñoäng caùc ñoái töôïng 

 
Ví duï 4.6 
// Allocating dynamic objects. 
#include <iostream.h> 
 
class samp { 
  int i, j; 
public: 
  void set_ij(int a, int b) { i=a; j=b; } 
  int get_product() { return i*j; } 
}; 
 
int main() 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

84

84 


  samp *p; 
  int i; 
 
  p = new samp [10];  

 

// allocate object array 

  if(!p) { 
    cout << "Allocation error\n"; 
    return 1; 
  } 
  for(i=0; i<10; i++)  

    p[i].set_ij(i, i); 

 
  for(i=0; i<10; i++) { 
    cout << "Product [" << i << "] is: "; 
    cout << p[i].get_product() << "\n"; 
  } 
 
  delete [] p

  return 0; 

 
 

• 

Khi con troû ñoái töôïng p ñöôïc giaûi phoùng, haøm huûy cuûa moãi phaàn töû ñöôïc goïi 

 
Ví duï 4.7 
// Allocating dynamic objects. 
#include <iostream.h> 
 
class samp { 
  int i, j; 
public: 
  void set_ij(int a, int b) { i=a; j=b; } 
  ~samp() { cout << "Destroying...\n"; } 
  int get_product() { return i*j; } 
}; 
 
 
 
int main() 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

85

85 


  samp *p; 
  int i; 
 
  p = new samp [10];  

 

// allocate object array 

  if(!p) { 
    cout << "Allocation error\n"; 
    return 1; 
  } 
 
  for(i=0; i<10; i++)  

p[i].set_ij(i, i); 

 
  for(i=0; i<10; i++) { 
    cout << "Product [" << i << "] is: "; 
    cout << p[i].get_product() << "\n"; 
  } 
 
  delete [] p

  return 0; 

 
@ Keát quaû cuûa chöông trình coù gì khaùc so vôùi ví duï 4.6 ? 
 
Baøi taäp IVb 
 
1. Haõy chuyeån ñoåi ñoaïn chöông trình sau ñeå duøng toaùn töû new 
 
char *p; 
p = (char *) malloc(100); 
// ... 
strcpy(p, "This is a test"); 
 
2/ Söû duïng toaùn töû new, caáp phaùt moät double vaø cho gaí trò ñaàu laø -3.1416 

 
 
V/ Tham chieáu (reference) 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

86

86 

1/ Moät tham chieáu laø moät con troû aån taùc ñoäng nhö moät teân khaùc ñoái vôùi moät bieán. 
 
Khai baùo :  data_type  &var 
 
Caùch söû duïng : 
+ Moät tham chieáu coù theå ñöôïc truyeàn cho haøm (goïi laø tham soá tham chieáu) . 
+ Moät tham chieáu coù theå ñöôïc traû veà bôûi haøm. 
+ Moät tham chieáu ñoäc laäp coù theå ñöôïc taïo ra. 
 
 

• 

Hoaït ñoäng cuûa tham soá tham chieáu (reference parameter) 

 
Ví duï 5.1 
#include <iostream.h>  
 
void  f(int *n);   

// use a pointer parameter 

 
int main() 

  int i = 0; 
 
  f(&i);  
 
  cout << "Here is i's new value: " << i << '\n'; 
  return 0; 

void f(int *n) 

  *n = 100;   // put 100 into the argument pointed to by n 

 
Haøm f() ñöôïc goïi laø ñòa chæ cuûa i trong main(). Do ñoù sau khi haøm f() traû veà, i coù giaù 
trò 100. 
 
Chöông trình naøy chöùng toû caùch con troû ñöôïc duøng nhö moät tham soá ñeå taïo ra moät cô 
cheá truyeàn tham soá goïi baèng tham chieáu

 

• 

Quaù trình treân coù theå thöïc hieän töï ñoäng baèng caùch duøng tham soá tham chieáu  

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

87

87 

 
Ví duï 5.2 
#include <iostream.h> 
 
void f(int &n) ;  

// declare a reference parameter 

 
int main() 

  int i = 0; 
 
  f(i);    
 
  cout << "Here is i's new value: " << i << '\n';   

// giaù trò cuûa i = ? 

  return 0; 

 
// f() now uses a reference parameter 
void f(int &n) 

  // notice that no * is needed in the following statement 
  n = 100;   // put 100 into the argument used to call f() 

 
n  laø moät bieán tham chieáu 
f() ñöôïc khai baùo nhö moät tham soá tham chieáu, ñiaï chæ ñoái vôùi soá ñöôïc truyeàn töï 
ñoäng cho f(). 
 
2/ Ñaëc tính 

• 

Khi söû duïng tham soá tham chieáu , trình bieân dòch seõ töï ñoäng truyeàn ñòa chæ cuûa 

bieán ñöôïc duøng nhö ñoái soá. Khoâng caàn taïo ra ñiaï chæ cuûa ñoái soá  baèng caùch ñaët 
tröôùc noù kyù töï &. 

• 

Beân trong haøm, trình bieân dòch töï ñoäng duøng bieán ñöôïc troû tôùi bôûi tham soá tham 

chieáu. Khoâng caàân duøng kyù töï *. Do ñoù, moät tham soá tham chieáu hoaøn toaøn thöïc 
hieän töï ñoäng cô cheá truyeàn ñoái soá baèng caùch goïi tham chieáu. 

• 

Khoâng theå thay ñoåi nhöõng gì maø moät tham chieáu troû tôùi. 

 
 
3/ Öu ñieåm cuûa tham soá tham chieáu 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

88

88 

+ Töø quan ñieåm thöïc haønh, khoâng caàn nhôù truyeàn ñiaï chæ cuûa moät ñoái soá . 
+ Tham soá tham chieáu taïo ra moät giao dieän ñeïp hôn so vôùi caùch duøng cô cheá con troû. 
+ Khi moät ñoái töôïng ñöôïc truyeàn cho moät haøm nhö moät tham chieáu thì khoâng coù baûn 
sao ñöôïc thöïc hieän. 
 

• 

Duøng caùc tham chieáu ñeå trao ñoåi 2 ñoái soá  nguyeân 

 
Ví duï 5.3 
#include <iostream.h> 
 
void swapargs(int &x, int &y); 
 
int main() 

  int i, j; 
 
  i = 10; 
  j = 19; 
 
  cout << "i: " << i << ", "; 
  cout << "j: " << j << "\n"; 
 
  swapargs(i, j); 
  cout << "After swapping: "; 
  cout << "i: " << i << ", "; 
  cout << "j: " << j << "\n"; 
  return 0; 

void swapargs(int &x, int &y) 

  int t; 
 
  t = x;   x = y; 

  y = t; 


 
 
Neáu duøng con troû thì haøm swapargs() ñöôïc vieát laïi nhö sau : 
void swapargs(int *x, int *y) 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

89

89 


  int t; 
 
  t = *x; 
  *x = *y; 
  *y = t; 

 

• 

Haøm round() laøm troøn moät giaù trò double. Giaù trò troøn ñöôïc truyeàn bôûi tham 

chieáu. 

 
Ví duï 5.4 
#include <iostream.h> 
#include <math.h> 
 
void round(double &num); 
 
int main() 

  double i = 100.4; 
 
  cout << i << " rounded is "; 
  round(i); 
  cout << i << "\n"; 
 
  i = 10.9; 
  cout << i << " rounded is "; 
  round(i); 
  cout << i << "\n"; 
 
  return 0; 

 
void round(double &num) 

  double frac; 
  double val; 
 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

90

90 

  // decompose num into whole and fractional parts 
  frac =  modf(num, &val); 
 
  if(frac < 0.5) num = val; 
  else num = val+1.0; 

 
 
Baøi taäp V 
 
1. Haõy vieát haøm neg() ñeå ñaûo ngöôïc daáu cuûa caùc tham soá nguyeân. Theo hai caùch : 

+ duøng tham soá con troû 

 

+ duøng tham soá tham chieáu 

 
2. Tìm loãi sai trong chöông trình sau : 
// This program has an error. 
#include <iostream.h> 
 
void triple(double &num); 
 
int main() 

  double d = 7.0; 
 
  triple(&d); 
  cout << d; 
  return 0; 

 
// Triple num's value. 
void triple(double &num) 

  num = 3 * num; 

 
VI/ Truyeàn tham chieáu cho ñoái töôïng 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

91

91 

Trong chöông 2, khi moät ñoái töôïng ñöôïc truyeàn cho moät haøm baèng caùch duøng cô cheá 
truyeàn tham soá goïi giaù trò, moät baûn sao ñoái töôïng ñöôïc taïo ra. Khi haøm traû veà, haøm 
huûy cuûa baûn sao ñoái töôïng ñöôïc goïi, ñieàu naøy coù theå sinh ra nhöõng vaán ñeà nghieâm 
troïng, chaúng haïn haøm huûy giaûi phoùng boä nhôù ñoäng. 
 
Khi truyeàn ñoái soá baèng tham chieáu, khoâng coù baûn sao ñoái töôïng ñöôïc taïo ra, do ñoù 
haøm huûy cuûa noù khoâng ñöôïc goïi khi caùc haøm traû veà. 
 
Tuy nhieân, nhöõng thay ñoåi ñoái vôùi ñoái töôïng ôû beân trong haøm coù aûnh höôûng ñeán ñoái 
töôïng ñöôïc duøng nhö ñoái soá. 
 
Khi moät ñoái töôïng ñöôïc truyeàn bôûi tham chieáu thì toaùn töû truy caäp thaønh vieân vaãn laø 
toaùn töû ñieåm (.) chöù khoâng phaûi toaùn töû muõi teân (->) . 
 
 

• 

Truyeàn ñoái töôïng baèng giaù trò cho haøm ñöôïc goïi f() 

 
Ví duï 6.1 
#include <iostream.h> 
 
class myclass { 
  int who; 
public: 
  myclass(int n) {  
    who = n; 
    cout << "Constructing " << who << "\n"; 
  } 
  ~myclass() { cout << "Destructing " << who << "\n"; } 
  int id() { return who; } 
}; 
 
 
// o is passed by value. 
void f(myclass o) 

  cout << "Received " << o.id() << "\n"; 

int main() 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

92

92 


  myclass  x(1); 
 
  f(x); 
 
  return 0; 

 
Keát quaû cuûa chöông trình 
 Constructing 

 Received 

 Destructing 

 Destructing 

 
Giaûi thích keát quaû ? 
 
 

• 

Truyeàn ñoái töôïng baèng tham chieáu cho haøm ñöôïc goïi f() 

 
Ví duï 6.2 
#include <iostream.h> 
 
class myclass { 
  int who; 
public: 
  myclass(int n) {  
    who = n; 
    cout << "Constructing " << who << "\n"; 
  } 
  ~myclass() { cout << "Destructing " << who << "\n"; } 
  int id() { return who; } 
}; 
 
// Now, o is passed by reference. 
void f(myclass &o) 

  // note that . operator is still used!!! 
  cout << "Received " << o.id() << "\n"; 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

93

93 


 
int main() 

  myclass  x(1); 
 
  f(x); 
 
  return 0; 

 
Keát quaû cuûa chöông trình 
 Constructing 

 Received 

 Destructing 

 
Giaûi thích keát quaû ? 
 
 
Baøi taäp VI 
 
1. Tìm loãi sai trong chöông trình sau. Söûa chöông trình theo caùc duøng  tham soá tham 
chieáu.  
 
// This program has an error. 
#include <iostream.h> 
#include <string.h> 
#include <stdlib.h> 
 
class strtype { 
  char *p; 
public: 
  strtype(char *s); 
  ~strtype() { delete [] p; } 
  char *get() { return p; } 
}; 
 
strtype::strtype(char *s) 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

94

94 


  int l; 
 
  l = strlen(s)+1; 
 
  p = new char [l]; 
  if(!p) { 
    cout << "Allocation error\n"; 
    exit(1); 
  } 
 
  strcpy(p, s); 

 
void show(strtype x) 

  char *s; 
    
  s = x.get(); 
  cout << s << "\n"; 

 
int main() 

  strtype a("Hello"), b("There"); 
 
  show(a); 
  show(b); 
 
  return 0; 

 
 
 
 
 
 

VII/ Traû veà caùc tham chieáu 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

95

95 

Moät haøm coù theå traû veà moät tham chieáu. Ñieàu naøy coù ích khi quaù taûi moät soá loaïi toaùn 
töû naøo ñoù. 
 
Moät haøm cuõng coù theå ñöôïc söû duïng ôû beân traùi cuûa caâu leänh gaùn. 
 
 

• 

Haøm traû veà moät tham chieáu. 

 
Ví duï 7.1 
// A simple example of a function returning a reference. 
 
#include <iostream.h> 
 
int  &f();  // return a reference 
int x; 
 
int main() 

  f() = 100;   // assign 100 to reference returned by f() 
 
  cout << x << "\n"; 
  return 0; 

 
// Return an int reference. 
int  &f() 

  return x;  // returns a reference to x 

 
Beân trong haøm f(), caâu leänh return x  khoâng traû veà giaù trò cuûa bieán toaøn cuïc, nhöng 
noù töï ñoäng traû veà ñiaï chæ cuûa x döôùi daïng tham chieáu. 
 
 

• 

Haøm traû veà moät tham chieáu, phaûi caån thaän khi ñoái töôïng tham chieáu khoâng ra 

ngoaøi phaïm vi. 

 
 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

96

96 

Ví duï 7.2 
// Return an int reference. 
int  &f() 

  int  x;  

// x is now a local variable 

  return x;    // returns a reference to x 

 
Do x laø bieán cuïc boä, seõ ra khoûi phaïm vi khi f() traû veà, nghiaõ laø tham chieáu ñöôïc traû 
veà bôûi f() laø voâ duïng.  
 
 

• 

Moät öùng duïng cuûa haøm traû veà moät tham chieáu duøng kieåm tra giôùi haïn bieân cuûa 

maûng. 

 
Ví duï 7.3 
// A simple bounded array example. 
#include <iostream.h> 
#include <stdlib.h> 
 
class array { 
  int size; 
  char *p; 
public: 
  array(int num); 
  ~array() { delete [] p; } 
  char &put(int i); 
  char get(int i); 
}; 
 
array::array(int num) 

  p = new char [num]; 
  if(!p) { 
    cout << "Allocation error\n"; 
    exit(1); 
  } 
  size = num; 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

97

97 


 
// Put something into the array. 
char &array::put(int i) 

  if(i<0 || i>=size) { 
    cout << "Bounds error!!!\n"; 
    exit(1); 
  } 
  return p[i];  // return reference to p[i] 

 
// Get something from the array. 
char array::get(int i) 

  if(i<0 || i>=size) { 
    cout << "Bounds error!!!\n"; 
    exit(1); 
  } 
  return p[i];  // return character 

   
int main() 

  array a(10); 
 
  a.put(3) = 'X'; 
  a.put(2) = 'R'; 
 
  cout << a.get(3) << a.get(2); 
  cout << "\n"; 
 
  // now generate run-time boundary error 
  a.put(11) = '!'; 
 
  return 0; 

 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

98

98 

Baøi taäp VII 
 
 
1. Haõy vieát chöông trình taïo maûng an toaøn hai chieàu 2x3 caùc soá nguyeân. 
 
2. Ñoaïn chöông trình sau coù ñuùng khoâng ? Taïi sao ?  
 
int &f(); 



int *x; 
 
x = f(); 
 
 
 

VIII/ Caùc tham chieáu ñoäc laäp vaø caùc haïn cheá 

 
1/ Tham chieáu ñoäc laäp (independent reference) laø moät bieán tham chieáu coù taùc duïng 
chæ laø moät teân khaùc cho moät bieán khaùc. 
 
Tham chieáu ñoäc laäp phaûi ñöôïc khôûi ñaàu khi khai baùo, do caùc tham chieáu khoâng theå 
ñöôïc gaùn nhöõng giaù trò môùi. 
 
Caùc laäp trình vieân thöôøng ít söû duïng tham chieáu ñoäc laäp. 
 
2/ Moät soá haïn cheá  
+ khoâng theå tham chieáu ñeán moät tham chieáu khaùc. 
+ khoâng theå coù ñiaï chæ cuûa tham chieáu. 
+ khoâng theå taïo moät maûng caùc tham chieáu 
+ khoâng theå tham chieáu moät tröôøng bit. 
+ caùc tham chieáu phaûi ñöôïc khôûi ñaàu tröø khi chuùng laø caùc thaønh vieân cuûa lôùp, laø caùc 
giaù trò traû veà hoaëc laø caùc tham soá cuûa haøm. 
 
 
 

• 

Chöông trình coù moät tham chieáu ñoäc laäp 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

99

99 

 
Ví duï 8.1 
#include <iostream.h> 
 
int main() 

  int x; 
  int  &ref = x;  

// create an independent reference 

 
  x = 10;   

 

// these two statements 

  ref = 10;     

// are functionally equivalent 

 
  ref = 100; 
  // this prints the number 100 twice 
  cout << x << ' ' << ref << "\n"; 
  return 0; 

 
 

• 

Moät tham chieáu ñoäc laäp coù theå tham chieáu ñeán moät haèng. 

 
Ví duï 8.2 
const  int  &ref = 10

 
 
 

 

 
 
 
 
 
 
 
 
 

Baøi taäp chöông 3 

 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

100 

100 

 

1. Cho lôùp sau, haõy taïo moät maûng hai chieàu 3x4 vaø cho moãi ñoái töôïng trong maûng 
moät giaù trò ñaàu. 
 
class  a_type { 
  double a, b; 
public: 
  a_type(double x, double y) { 
    a = x;  
    b = y; 
  } 
  void show() { cout << a << ' ' << b << "\n"; } 
}; 
 
2. Haõy thay ñoåi lôøi giaûi ñoái vôùi baøi toaùn treân ñeå coù theå truy caäp maûng baèng caùch 
duøng con troû. 
 
3. Haõy taïo haøm recip() nhaän moät tham soá tham chieáu  double. Haõy cho haøm naøy thay 
ñoåi giaù trò cuûa tham soá ñoù. Haõy vieát moät chöông trình cho haøm naøy hoaït ñoäng. 
 
4. Haõy söûa ñoåi chöông trình sau vôùi toaùn töû new vaø delete 
 
#include <iostream.h> 
#include <string.h> 
#include <stdlib.h> 
#include <malloc.h> 
 
class strtype { 
  char *p; 
  int len; 
public: 
  strtype(char *ptr); 
  ~strtype(); 
  void show(); 
}; 
 
strtype::strtype(char *ptr) 

background image

Chöông 3       Maûng, Con troû, Tham chieáu   

 

 

101 

101 

  len = strlen(ptr); 
  p = (char *) malloc(len+1); 
  if(!p) { 
    cout << "Allocation error\n"; 
    exit(1); 
  } 
  strcpy(p, ptr); 

 
strtype::~strtype() 

  cout << "Freeing p\n"; 
  free(p); 

 
void strtype::show() 

  cout << p << " - length: " << len; 
  cout << "\n"; 

 
int main() 

  strtype s1("This is a test."), s2("I like C++."); 
 
  s1.show(); 
  s2.show(); 
 
  return 0; 

 
 
5. Haõy söûa ñoåi chöông trình treân ñeå duøng vôùi tham chieáu 
 
 
 
 

background image

 

 

 
 

Chöông 4   
 
 

Quaù taûi haøm 

 
 
 
 
 
 
 
 

• 

Quaù taûi haøm taïo 

 

• 

Haøm taïo baûn sao 

 

• 

Haøm vôùi caùc ñoái soá maëc ñònh 

 

• 

Tính khoâng xaùc ñònh khi quaù taûi haøm 

 

• 

Ñiaï chæ cuûa haøm quaù taûi 

 
 
 
 
 

 

 
 
 
 
 
 

background image

Chöông 4    Quaù taûi haøm  

 

104 

104 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 4    Quaù taûi haøm  

 

105 

105 

I/ Quaù taûi haøm taïo (

constructor overloading )

 

 
Coù theå quaù taûi haøm taïo cuûa moät lôùp, nhöng khoâng quaù taûi haøm huûy.  
 
Haøm taïo cuûa lôùp phaûi phuø hôïp vôùi caùch maø ñoái töôïng cuûa lôùp ñoù ñöôïc khai baùo. Neáu 
khoâng loãi thôøi gian bieân dòch seõ xaûy ra. 
 
Coù 3 lyù do caàn quaù taûi  haøm taïo : 

+ ñeå coù tính linh hoaït 
+ ñeå hoå trôï maûng 
+ ñeå taïo caùc haøm taïo baûn sao 

 
Haïn cheá : neáu thöïc hieän quaù taûi nhieàu laàn coù theå taïo ra taùc duïng huûy hoaïi treân lôùp. 
 
 

• 

Quaù taûi haøm taïo vôùi khôûi ñaàu moät ñoái töôïng hoaëc khoâng khôûi ñaàu ñoái töôïng 

Ví duï 1.1 
#include <iostream.h> 
 
class myclass { 
  int x; 
public: 
  // overload constructor two ways 
  myclass() { x = 0; }  

 

// no initializer 

  myclass(int n) { x = n; }   

// initializer 

  int getx() { return x; } 
}; 
 
int main() 

  myclass o1(10);    

// declare with initial value 

  myclass o2;  

 

// declare without initializer 

 
  cout << "o1: " << o1.getx() << '\n'; 
  cout << "o2: " << o2.getx() << '\n'; 
  return 0; 

background image

Chöông 4    Quaù taûi haøm  

 

106 

106 

• 

Quaù taûi haøm taïo ñeå cho caùc ñoái töôïng rieâng leõ laãn caùc maûng ñoái töôïng xaûy ra 

trong chöông trình. 

 
Ví duï 1.2 
#include <iostream.h> 
 
class myclass { 
  int x; 
public: 
  // overload constructor two ways 
  myclass() { x = 0; }  

 

// no initializer 

  myclass(int n) { x = n; }   

// initializer 

 
  int getx() { return x; } 
}; 
 
int main() 

  myclass o1[10];    

 

 

 

// declare array without initializers 

  myclass o2[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // declare with initializers 
 
  int i; 
 
  for(i=0; i<10; i++) { 
    cout << "o1[" << i << "]: " << o1[i].getx(); 
    cout << '\n'; 
    cout << "o2[" << i << "]: " << o2[i].getx(); 
    cout << '\n'; 
  } 
 
  return 0; 

 
 

• 

Quaù taûi haøm taïo giuùp laäp trình vieân choïn phöông phaùp thuaän lôïi nhaát ñeå khôûi 

ñaàu moät ñoái töôïng. 

 

background image

Chöông 4    Quaù taûi haøm  

 

107 

107 

Ví duï 1.3 
#include <iostream.h> 
#include <stdio.h>    

// included for sscanf() 

 
class date { 
  int day, month, year; 
public: 
  date(char *str)
  date (int m, int d, int y) { 
    day = d; 
    month = m; 
    year = y; 
  } 
 
  void show() { 
    cout << month << '/' << day << '/'; 
    cout << year << '\n'; 
  } 
}; 
  
date::date(char *str) 

  sscanf(str, "%d%*c%d%*c%d", &month, &day, &year); 

 
int main() 

  // construct date object using string 
  date  sdate("12/31/99")
 
  // construct date object using integers 
  date  idate(12, 31, 99)
 
  sdate.show(); 
  idate.show(); 
  return 0; 

background image

Chöông 4    Quaù taûi haøm  

 

108 

108 

• 

Quaù taûi haøm taïo khi maûng ñoäng cuûa lôùp ñöôïc caáp phaùt. Ñieàu naøy giuùp giaûi 

quyeát haïn cheá trong chöông 3, phaàn IV/2, moät maûng ñoäng khoâng theå ñöôïc khôûi 
ñaàu, xem ví duï 4.6. 

 
Ví duï 1.4 
#include <iostream.h> 
 
class myclass { 
  int x; 
public: 
  // overload constructor two ways 
  myclass() { x = 0; }  

 

// no initializer 

  myclass(int n) { x = n; }   

// initializer 

  int getx() { return x; } 
  void setx(int n) { x = n; } 
}; 
 
int main() 

  myclass *p; 
  myclass ob(10);     

// initialize single variable 

 
  p = new myclass[10];   // can't use initializers here 
  if(!p) { 
    cout << "Allocation error\n"; 
    return 1; 
  } 
 
  int i; 
 
  // initialize all elements to ob 
  for(i=0; i<10; i++)  

p[i] = ob

 
  for(i=0; i<10; i++) { 
    cout << "p[" << i << "]: " << p[i].getx(); 
    cout << '\n'; 
  } 

background image

Chöông 4    Quaù taûi haøm  

 

109 

109 

 
  return 0; 

 
 
Baøi taäp I 
 
1. Cho lôùp sau, haõy boå sung hai haøm taïo. Haøm taïo thöù nhaát khoâng nhaän tham soá, 
haøm naøy duøng toaùn töû new caáp phaùt 255 bytes boä nhôù, khôûi ñaàu boä nhôù nhö moät 
chuoãi roãng vaø cho len = 255. Haøm taïo thöù hai nhaän hai tham soá, tham soá thöù nhaát laø 
chuoãi duøng ñeå khôûi ñaàu vaø tham soá kia laø soá byte ñeå caáp phaùt. Cho phieân baûn naøy 
caáp phaùt löôïng boä nhôù ñaõ ñöôïc chæ roõ vaø cheùp chuoåi vaøo boä nhôù.  
 
Thöïc hieän vieäc kieåm tra giôùi haïn bieân caàn thieát vaø chöùng toû caùc haøm taïo seõ hoaït 
ñoäng qua moät chöông trình ngaén. 
 
class strtype { 
  char *p; 
  int len; 
public: 
  char *getstring() { return p; } 
  int  getlength() { return len; } 
}; 
 
 
2. Töø baøi taäp II, 2  chöông 2, boå sung haøm taïo khoâng nhaän tham soá vaø moät phieân baûn 
ñöôïc quaù taûi ñeå nhaän giôø heä thoáng döôùi daïng ñöôïc traû veà bôûi haøm chuaån clock(). 
 
 

II/ Taïo vaø söû duïng haøm taïo baûn sao 

(copy constructor)

 

 
1/ Khaùi nieäm 

Haøm taïo baûn sao

 laø kieåu ñaëc bieät cuûa haøm taïo ñöôïc quaù taûi. 

 
Khi moät ñoái töôïng ñöôïc truyeàn cho moät haøm,  baûn sao töøng bit moät cuûa ñoái töôïng ñoù 
ñöôïc taïo ra vaø ñöôïc truyeàn cho tham soá cuûa haøm ñeå nhaän ñoái töôïng.  

background image

Chöông 4    Quaù taûi haøm  

 

110 

110 

Tuy nhieân, coù nhöõng tröôøng hôïp trong ñoù baûn sao ñoàng nhaát laø nhö khoâng mong 
muoán.  
 
Chaúng haïn, neáu ñoái töôïng coù con troû tôùi boä nhôù ñöôïc caáp phaùt, thì baûn sao seõ troû tôùi 
cuøng boä nhôù 

nhö ñoái töôïng goác ñaõ laøm. Do ñoù, neáu baûn sao taïo ra söï thay ñoåi cho noäi 

dung boä nhôù thì noù cuõng seõ ñöôïc thay ñoåi ñoái vôùi ñoái töôïng goác. Khi moät haøm keát 
thuùc, baûn sao seõ bò huûy vaø haøm huûy cuûa noù ñöôïc goïi. Ñieàu naøy daãn ñeán nhöõng taùc 
duïng khoâng mong muoán laøm aûnh höôûng ñeán ñoái töôïng goác. 
 
Khi moät ñoái töôïng ñöôïc traû veà töø moät haøm tình traïng töông töï cuõng seõ xaûy ra. Trình 
bieân dòch seõ taïo ra moät ñoái töôïng taïm ñeå giöõ baûn sao cuûa giaù trò do haøm traû veà. Ñoái 
töôïng taïm naøy seõ ra khoûi phaïm vi moät khi giaù trò ñöôïc traû veà cho thuû tuïc goïi, khieán 
haøm huûy cuûa ñoái töôïng taïm ñöôïc goïi. Neáu haøm huûy huûy boû thöù gì caàn cho thuû tuïc 
goïi, chaúng haïn noù giaûi phoùng boä nhôù caáp phaùt ñoäng, thì raéc roái seõ xaûy ra. 
 
Nhö vaäy, coát loõi cuûa vaán ñeà treân laø baûn sao töøng bit cuûa ñoái töôïng ñöôïc taïo ra vaø 
thöïc hieän

. Ñeå ngaên chaën vaán ñeà naøy, laäp trình vieân caàn xaùc ñònh chính xaùc nhöõng gì 

xaûy ra khi baûn sao cuûa moät ñoái töôïng ñöôïc thöïc hieän ñeå traùnh ñöôïc nhöõng taùc duïng 
khoâng mong muoán. 
 

 

Haøm taïo baûn sao seõ giaûi quyeát ñöôïc vaán ñeà treân. Khi ñònh nghóa haøm taïo baûn sao, 
laäp trình vieân coù theå hoaøn toaøn kieåm soaùt chính xaùc nhöõng gì xaûy ra khi baûn sao cuûa 
moät ñoái töôïng ñöôïc thöïc hieän. 
 
 

• 

Caàn phaân bieät hai tröôøng hôïp trong ñoù giaù trò cuûa moät ñoái töôïng ñöôïc truyeàn cho 

ñoái töôïng khaùc : 

 
+ Tröôøng hôïp thöù nhaát laø pheùp gaùn
+ Tröôøng hôïp thöù hai laø söï khôûi ñaàu, coù theå xaûy ra theo 3 caùch : 

 

- Khi moät ñoái töôïng ñöôïc duøng ñeå khôûi ñaàu moät ñoái töôïng khaùc trong  

caâu leänh khai baùo. 

 

- Khi moät ñoái töôïng ñöôïc truyeàn nhö tham soá cho haøm. 

 

- Khi moät ñoái töôïng taïm ñöôïc taïo ra duøng ñeå laøm giaù trò traû veà bôûi moät haøm. 

 
Haøm taïo baûn sao chæ aùp duïng cho söï khôûi ñaàu. Noù khoâng aùp duïng cho pheùp gaùn.  
Haøm taïo baûn sao khoâng aûnh höôûng ñeán caùc pheùp gaùn. 

background image

Chöông 4    Quaù taûi haøm  

 

111 

111 

2/ Cuù phaùp  
 

• 

Daïng toång quaùt cuûa haøm taïo baûn sao  

 

classname(const classname &obj{ 

 

 

// body of constructor 

 
     obj  

laø moät tham chieáu tôùi moät ñoái töôïng ñöôïc duøng ñeå khôûi ñaàu moät ñoái töôïng 

khaùc 
 
 

• 

Daïng môû roäng cuûa haøm taïo baûn sao (coù nhieàu ñoái soá) 

 

classname(const classname &obj, int x = 0) { 

  // body of constructor 

 
Ñoái soá thöù nhaát laø moät tham chieáu tôùi ñoái töôïng ñöôïc sao cheùp, vaø caùc ñoái töôïng 
khaùc ñeàu maëc ñònh. Tính linh hoaït naøy cho pheùp taïo ra caùc haøm taïo baûn sao coù 
nhöõng coâng duïng khaùc. 
 
Ví duï

, lôùp ñöôïc goïi laø myclass vaø y laø ñoái töôïng cuûa myclass thì caùc leänh sau ñaây seõ 

duøng ñeán haøm taïo baûn sao cuûa myclass : 
 

myclass x = y;  

// y explicitly initializing x 

func1(y);        

// y passed as a parameter 

y = func2();    

// y receiving a returned object 

 
Trong hai tröôøng hôïp ñaàu, moät tham chieáu tôùi y seõ ñöôïc truyeàn cho haøm taïo baûn sao. 
Tröôøng hôïp thöù ba, moät tham chieáu tôùi ñoái töôïng ñöôïc traû veà bôûi func2() seõ ñöôïc 
truyeàn cho haøm taïo baûn sao. 
 
 

• 

Taïo moät maûng soá nguyeân "an toaøn" coù kieåm tra giôùi haïn bieân 

 
Ví duï 2.1 

background image

Chöông 4    Quaù taûi haøm  

 

112 

112 

/*  This program creates a "safe" array class. Since space for the array is 
dynamically allocated, a copy constructor is provided to allocate memory when 
one array object is   used to initialize another. */ 

 
#include <iostream.h> 
#include <stdlib.h> 
 
class array { 
  int *p; 
  int size; 
public: 
  array(int sz) {  

// constructor 

    p = new int[sz]; 
    if(!p) exit(1); 
    size = sz; 
    cout << "Using 'normal' constructor\n"; 
  } 
  ~array() {delete [] p;} 
 
  // copy constructor 
  array(const  array &a)
 
  void put(int i, int j) { 
    if(i>=0 && i<size) p[i] = j; 
  } 
 
  int get(int i) { 
    return p[i]; 
  } 
}; 
 
 
/* Copy constructor. 
In the following, memory is allocated specifically for the copy, and the address of 
this memory is assigned to p. Therefore, p is not pointing to the same dynamically 
allocated memory as the original object. */ 
array::array(const array &a)

 { 

background image

Chöông 4    Quaù taûi haøm  

 

113 

113 

  int i; 
  size = a.size; 
  p = new int[a.size];  // allocate memory for copy 
  if(!p) exit(1); 
  for(i=0; i<a.size; i++) p[i] = a.p[i]; // copy contents 
  cout << "Using copy constructor\n"; 

 
int main() 
{  
  array num(10);    // this calls "normal" constructor 
  int i; 
 
  // put some values into the array 
  for(i=0; i<10; i++)  

num.put(i, i); 

 
  // display num 
  for(i=9; i>=0; i--)   cout << num.get(i); 
  cout << "\n"; 
 
  // create another array and initialize with num 
  array x = num;    // this invokes copy constructor 
 
  // display x 
  for(i=0; i<10; i++)  

cout << x.get(i); 

 
  return 0; 

 
@ Coù nhaän xeùt gì veà keát quaû khi chöông trình naøy khoâng söû duïng haøm taïo baûn sao ? 
 
 
@ Nhöõng caâu leänh sau khoâng theå goïi ñöôïc haøm taïo baûn sao, taïi sao ? 

array a(10); 
array b(10); 
b = a;   

// does not call copy constructor 

background image

Chöông 4    Quaù taûi haøm  

 

114 

114 

• 

Haøm taïo baûn sao giuùp ngaên ngöøa moät soá vaán ñeà lieân quan ñeán vieäc truyeàn caùc 

kieåu ñoái töôïng naøo ñoù cho haøm. 

 
 
Ví duï 2.2 
// This program has an error. 
#include <iostream.h> 
#include <string.h> 
#include <stdlib.h> 
 
class strtype { 
  char *p; 
public: 
  strtype(char *s); 
  ~strtype() { delete [] p; } 
  char *get() { return p; } 
}; 
 
strtype::strtype(char *s) 

  int l; 
  l = strlen(s)+1; 
 
  p = new char [l]; 
  if(!p) { 
    cout << "Allocation error\n"; 
    exit(1); 
  } 
  strcpy(p, s); 

 
void show(strtype x) 

  char *s; 
  s = x.get(); 
  cout << s << "\n"; 

background image

Chöông 4    Quaù taûi haøm  

 

115 

115 

int main() 

  strtype a("Hello"), b("There"); 
  show(a); 
  show(b); 
  return 0; 

 
@ Haõy tìm nguyeân nhaân gaây ra loãi ? 
 
 
Ví duï 2.3 

Hieäu chænh chöông trình trong ví duï 2.2 

/* This program uses a copy constructor to allow strtype objects to be passed to 
functions. */ 
#include <iostream.h> 
#include <string.h> 
#include <stdlib.h> 
 
class strtype { 
  char *p; 
public: 
  strtype(char *s);    

 

// constructor 

  strtype(const strtype &o);  

// copy constructor 

  ~strtype() { delete [] p; }  

// destructor 

  char *get() { return p; } 
}; 
 
// "Normal" constructor 
strtype::strtype(char *s) 

  int l; 
  l = strlen(s)+1; 
 
  p = new char [l]; 
  if(!p) { 
    cout << "Allocation error\n"; 
    exit(1); 

background image

Chöông 4    Quaù taûi haøm  

 

116 

116 

  } 
  strcpy(p, s); 

 
// Copy constructor 
strtype::strtype(const  strtype  &o) 

  int l; 
 
  l = strlen(o.p)+1; 
  p = new char [l]; // allocate memory for new copy 
  if(!p) { 
    cout << "Allocation error\n"; 
    exit(1); 
  } 
 
  strcpy(p, o.p);  

// copy string into copy 


 
void show(strtype x) 

  char *s; 
    
  s = x.get(); 
  cout << s << "\n"; 

 
int main() 

  strtype a("Hello"), b("There"); 
 
  show(a); 
  show(b); 
 
  return 0; 

 

background image

Chöông 4    Quaù taûi haøm  

 

117 

117 

Baøi taäp II 
 
1. Xeùt chöông trình sau, haõy giaûi thích taïi sao coù keát quaû naøy ? 
 Constructing 

normally 

Constructing normally 
Constructing copy 
 

#include <iostream.h> 
 
class myclass { 
public: 
  myclass(); 
  myclass(const myclass &o)
  myclass f(); 
}; 
 
myclass::myclass()   

// Normal constructor 


  cout << "Constructing normally\n"; 

 
myclass::myclass(const myclass &o) 

// Copy constructor 


  cout << "Constructing copy\n"; 

 
myclass myclass::f() 

 

// Return an object. 


  myclass temp; 
  return temp; 

 
int main() 

  myclass obj; 
  obj = obj.f(); 
  return 0; } 

background image

Chöông 4    Quaù taûi haøm  

 

118 

118 

2. Tìm loãi sai trong chöông trình vaø yeâu caàu chænh lyù ? 
#include <iostream.h> 
#include <stdlib.h> 
 
class myclass { 
  int *p; 
public: 
  myclass(int i); 
  ~myclass() { delete p; } 
  friend int getval(myclass o); 
}; 
 
myclass::myclass(int i) 

  p = new int; 
 
  if(!p) { 
    cout << "Allocation error\n"; 
    exit(1); 
  } 
  *p = i; 

 
int getval(myclass o) 
{  
  return *o.p; // get value 

 
int main() 

  myclass a(1), b(2); 
 
  cout << getval(a) << " " << getval(b)  << "\n"; 
  cout << getval(a) << " " << getval(b); 
 
  return 0; 

background image

Chöông 4    Quaù taûi haøm  

 

119 

119 

III/ Söû duïng caùc ñoái soá maëc ñònh 

(default  argument) 

 

• 

Ñoái soá maëc ñònh

 cho pheùp gaùn moät giaù trò maëc ñònh cho moät tham soá khi khoâng 

coù ñoái soá töông öùng ñöôïc chæ roõ khi haøm ñöôïc goïi. 

 

Ñoái soá maëc ñònh lieân quan ñeán söï quaù taûi haøm, söû duïng caùc ñoái soá maëc ñònh chuû 
yeáu laø daïng ngaén cuûa quaù taûi haøm. 

 

• 

Ñeå gaùn moät ñoái soá maëc ñònh cho moät tham soá thì sau tham soá phaûi coù daáu baèng 

vaø moät giaù trò muoán maëc ñònh neáu khoâng coù ñoái soá töông öùng khi haøm ñöôïc goïi.  

 
 
Ví duï 3.1

    

 
// A simple first example of default arguments. 
#include <iostream.h> 
 
void f(int a = 0, int b = 0) 

  cout << "a: " << a << ", b: " << b; 
  cout << '\n'; 

 
int main() 

  f(); 
  f(10); 
  f(10, 99); 
 
  return 0; 

 
 
Haøm f() cho hai giaù trò maëc ñònh 0 ñoái vôùi caùc tham soá  

void  f(int  a = 0, int  b = 0); 

 
Cuù phaùp naøy töông töï nhö khôûi ñaàu moät bieán. 

background image

Chöông 4    Quaù taûi haøm  

 

120 

120 

Haøm f() coù theå goïi theo 3 caùch : 
+ noù ñöôïc goïi vôí caû hai ñoái soá ñöôïc chæ roõ. 
+ noù ñöôïc goïi chæ vôí ñoái soá thöù nhaát ñöôïc chæ roõ. Tröôøng hôïp naøy, b seõ maëc ñònh veà 
0. 
+ f() coù theå ñöôïc goïi laø khoâng coù ñoái soá , a vaø b maëc ñònh veà 0. 
 
nghiaõ laø caùc caâu leänh sau ñeàu ñuùng : 

f() ;    

// a and b default to 0 

f(10) ;  

 

// a is 10, b defaults to 0 

f(10, 99) ;   // a is 10, b is 99 

 
Löu yù, trong ví duï naøy, khoâng coù caùch ñeå maëc ñònh a vaø chæ roõ b . 
 
 

• 

Khi ñoái soá maëc ñònh ñaàu tieân ñöôïc chæ roõ, taát caû caùc tham soá theo sau cuõng phaûi 

coù maëc ñònh. Ví duï moät phieân baûn khaùc cuûa f() sau ñaây seõ taïo ra loãi thôøi gian 
bieân dòch : 

 

void f(int  a = 0, int  b)  

// wrong!  b must have default, too 


  cout << "a: " << a << ", b: " << b; 
  cout << '\n'; 

 
 

• 

Qui taéc   

Khi taïo moät haøm coù moät hay nhieàu ñoái soá maëc ñònh thì nhöõng ñoái soá ñoù phaûi 
chæ roõ moät laàn

 hoaëc trong ñònh nghiaõ cuûa haøm hoaëc trong nguyeân maãu cuûa noù 

chöù khoâng ñöôïc caû hai.  
 
Qui taéc naøy aùp duïng ngay caû khi chæ nhaân ñoâi caùc ngaàm ñònh gioáng nhau.   

 

• 

Taát caû caùc tham soá maëc ñònh phaûi ôû beân phaûi cuûa caùc tham soá khoâng coù maëc 

ñònh. Hôn nöõa, khi baét ñaàu ñònh nghóa caùc tham soá maëc ñònh, khoâng theå chæ ñònh 
caùc tham soá khoâng coù maëc ñònh.  

 

• 

Vôùi caùc ñoái soá maëc ñònh, chuùng phaûi laø caùc haèng hoaëc laø caùc bieán toaøn cuïc. 

background image

Chöông 4    Quaù taûi haøm  

 

121 

121 

Ví duï 3.2 

Caùc ñoái soá maëc ñònh lieân quan ñeán söï quaù taûi haøm  

 
// Compute area of a rectangle using overloaded functions. 
#include <iostream.h> 
 
// Return area of a non-square rectangle. 
double rect_area(double length, double width) 

  return length * width; 

 
// Return area of a square. 
double rect_area(double length) 

  return length * length; 

 
int main() 

  cout  << "10 x 5.8 rectangle has area: "; 
  cout << rect_area(10.0, 5.8) << '\n'; 
 
  cout  << "10 x 10 square has area: "; 
  cout << rect_area(10.0) << '\n'; 
  return 0; 

 
 
Ví duï 3.3 

Thöïc söï khoâng caàn coù hai haøm rect_area() khaùc nhau. Thay vaøo ñoù, 

tham soá thöù hai coù theå ñöôïc maëc ñònh veà giaù trò naøo ñoù taùc ñoäng nhö coøi hieäu cho 
haøm rect_area() 
 
// Compute area of a rectangle using default arguments. 
#include <iostream.h> 
 
// Return area of a rectangle. 
 

background image

Chöông 4    Quaù taûi haøm  

 

122 

122 

double rect_area(double length, double width = 0

  if(!width) width = length; 
  return length * width; 

int main() 

  cout  << "10 x 5.8 rectangle has area: "; 
  cout << rect_area(10.0, 5.8) << '\n'; 
 
  cout  << "10 x 10 square has area: "; 
  cout << rect_area(10.0) << '\n'; 
  return 0; 

 
@ Nhö vaäy, caùc ñoái soá ngaàm ñònh thöôøng ñöa ra caùch ñôn giaûn ñeå quaù taûi haøm. 
 
 

• 

Trong phaàn tröôùc, moät haøm taïo ñöôïc quaù taûi chiû cho pheùp taïo ra caùc ñoái töôïng 

ñöôïc khôûi ñaàu vaãn khoâng ñöôïc khôûi ñaàu. Trong nhieàu tröôøng hôïp, coù theå traùnh 
quaù taûi moät haøm taïo baèng caùch cho noù moät hay nhieàu ñoái soá ngaàm ñònh

 

Ví duï 3.4 
#include <iostream.h> 
 
class myclass { 
  int x; 
public: 
  /*  Use default argument instead of overloading myclass's constructor. */ 
  myclass(int n = 0) { x = n; } 
  int getx() { return x; } 
}; 
 
int main() 

  myclass o1(10);   // declare with initial value 
  myclass o2;  

 

// declare without initializer 

background image

Chöông 4    Quaù taûi haøm  

 

123 

123 

  cout << "o1: " << o1.getx() << '\n'; 
  cout << "o2: " << o2.getx() << '\n'; 
 
  return 0; 

 
@ Nhö vaäy, baèng caùch cho bieán n giaù trò maëc ñònh zero, coù theå taïo ra caùc ñoái töôïng 
coù caùc giaù trò ñaàu roõ raøng vaø caùc ñoái töôïng coù giaù trò maëc ñònh laø ñuû. 
 
 

• 

Ñoái soá maëc ñònh ñöôïc tìm thaáy khi moät tham soá ñöôïc duøng ñeå choïn moät tuøy 

choïn. 

 
Ví duï 3.5 
#include <iostream.h> 
#include <ctype.h> 
 
const  int  ignore = 0; 
const  int  upper = 1; 
const  int  lower = 2; 
 
void print(char *s, int how = -1) ; 
 
int main() 

  print("Hello There\n", ignore); 
  print("Hello There\n", upper); 
  print("Hello There\n");    

// continue in upper 

  print("Hello there\n", lower); 
  print("That's all\n");   

 

// continue in lower 

  return 0; 

 
/* Print a string in the specified case. Use last case specified if none is given. */ 
void print(char *s, int how) 

  static int oldcase = ignore; 

background image

Chöông 4    Quaù taûi haøm  

 

124 

124 

 
  // reuse old case if none specified 
  if(how < 0)  how = oldcase;  
  while(*s) { 
     switch(how) { 
           case  upper  : cout << (char) toupper(*s); 
                                   break; 
           case  lower  : cout << (char) tolower(*s); 
                                   break; 
           default : cout << *s; 
    } 
    s++; 
  } 
  oldcase = how; 

 
 

• 

Thöïc söï, vieäc cung caáp ñoái soá  maëc ñònh khi khoâng ñöôïc goïi seõ laøm hoûng 

chöông    trình vaø seõ höôùng daãn sai cho ngöôøi khaùc söû duïng haøm ñoù. 

 

Vôùi söï quaù taûi haøm, moät laäp trình vieân thaønh thaïo seõ bieát ñöôïc khi naøo thì söû 
duïng ñoái soá maëc ñònh vaø khi naøo khoâng. 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 4    Quaù taûi haøm  

 

125 

125 

Baøi taäp III 
 
 
1. Tìm loãi sai trong nguyeân maãu haøm sau : 
 

char  *f(char  *p, int  x = 0 , char *q) ; 

 
 
2. Tìm loãi sai trong nguyeân maãu duøng ñoái soá maëc ñònh sau : 
 

int  f(int count, int  max = count) ; 

 
 
3. Trong thö vieän chuaån C++ coù haøm strtol(), coù nguyeân maãu sau : 
 

long strtol(const char *start, const **end, int base); 

Haøm naøy chuyeån ñoåi chuoãi soá ñöôïc troû tôùi bôûi start thaønh soá nguyeân daøi. 
 
Haõy taïo haøm mystrtol() hoaït ñoäng gioáng nhö strtol() vôùi ngoaïi leä laø base ñöôïc cho 
moät ñoái soá  maëc ñònh laø 10. Vieát chöông trình chöùng toû haøm mystrtol() hoaït ñoäng toát. 
 
 
4. Haõy taïo haøm myclreol() ñeå xoaù doøng töø vò trí con troû hieän taïi ñeán cuoái doøng. Haøm 
naøy coù moät tham soá chæ roõ vò trí cuûa kyù töï caàn xoaù. Neáu khoâng chæ roõ tham soá thì toaøn 
boä doøng seõ töï ñoäng bò xoaù. Ngöôïc laïi, chæ xoaù nhöõng vò trí naøo ñöôïc chæ roõ bôûi tham 
soá. 
 
 
 
 
 
 
 
 
 
 
 
 
 

IV/ Söï quaù taûi vaø tính khoâng xaùc ñònh 

(ambiguity)

 

background image

Chöông 4    Quaù taûi haøm  

 

126 

126 

 
Khi quaù taûi haøm, coù theå daãn ñeán tính khoâng xaùc ñònh trong chöông trình. 
 
Tính khoâng xaùc ñònh 

do quaù taûi gaây ra coù theå ñöôïc ñöa vaøo thoâng qua : 

 +  caùc chuyeån ñoåi kieåu 
 +  caùc tham soá tham chieáu 
 +  caùc ñoái soá  maëc ñònh 
 +  hoaëc do chính caùc haøm ñöôïc quaù taûi 
 +  hoaëc do caùch goïi caùc haøm quaù taûi 
 
Tính khoâng xaùc ñònh phaûi ñöôïc loaïi boû tröôùc khi chöông trình ñöôïc bieân dòch. 
 
 

• 

Tính khoâng xaùc ñònh gaây ra bôûi caùc quy taéc chuyeån ñoåi kieåu töï ñoäng trong C++ 

  
Ví duï 4.1 
// This program contains an ambiguity error
#include <iostream.h> 
 
float f(float i) 

  return i / 2.0; 

 
double f(double i) 

  return i / 3.0; 

 
int main() 

  float x = 10.09; 
  double y = 10.09; 
 
  cout << f(x);  

 

// unambiguous - use f(float) 

  cout << f(y);  

 

// unambiguous - use f(double) 

 

background image

Chöông 4    Quaù taûi haøm  

 

127 

127 

  cout << f(10);  

// ambiguous, convert 10 to double or float?? 

  return 0; 

 
@ Loãi bieân dòch coù daïng    Error : Ambiguity between 'f(float)' and 'f(double)' 
 
@ Ví duï treân minh hoïa tính khoâng xaùc ñònh coù theå xaûy ra khi moät haøm quaù taûi ñöôïc 
goïi. 
 

• 

Khi haøm ñöôïc goïi vôùi kieåu ñoái soá sai, caùc quy taéc chuyeån ñoåi töï ñoäng cuûa C++ 

gaây ra tình traïng khoâng xaùc ñònh. Baûn thaân söï quaù taûi haøm ôû ví duï naøy töï noù 
khoâng coù tính khoâng xaùc ñònh. 

 
Ví duï 4.2 
 
// This program is ambiguous. 
#include <iostream.h> 
 
void f(unsigned char c) 

  cout << c; 

  
void f(char c) 

  cout << c; 

 
 
int main() 

  f('c'); 
  f(86);  

// which f() is called??? 

 
  return 0; 

background image

Chöông 4    Quaù taûi haøm  

 

128 

128 

• 

Tính khoâng xaùc ñònh xaûy ra do quaù taûi caùc haøm, trong ñoù coù söï khaùc bieät duy 

nhaát laø moät haøm söû duïng moät tham soá tham chieáu vaø haøm kia söû duïng tham soá 
maëc ñònh goïi baèng giaù trò. 

  
Ví duï 4.3 
 
// An ambiguous program. 
#include <iostream.h> 
 
int f(int a, int b) 

  return a+b; 

 
// this is inherently ambiguous 
int  f(int a, int &b) 

  return a-b; 

 
 
int main() 

  int x=1, y=2; 
 
  cout << f(x, y);   // which version of f() is called??? 
 
  return 0; 

 
 
@ Loãi bieân dòch ôû haøm f(int a, int &b) coù daïng 
 

Error : 'f(int, int &)' cannot be distinguished from 'f(int, int)' 

 
 
 
 

background image

Chöông 4    Quaù taûi haøm  

 

129 

129 

• 

Tính khoâng xaùc ñònh xaûy ra do quaù taûi haøm, trong ñoù coù moät hay nhieàu haøm 

ñöôïc quaù taûi duøng moät ñoái soá maëc ñònh. 

  
Ví duï 4.4 
 
// Ambiguity based on default arguments plus overloading. 
#include <iostream.h> 
 
int  f(int a) 

  return a*a; 

 
 
int  f(int a, int b = 0) 

  return a*b; 

 
 
int main() 

  cout << f(10, 2);   // calls f(int, int) 
 
  cout << f(10);  

// ambiguous - call f(int) or f(int, int)??? 

 
  return 0; 

 
 
 
 
 
 
 
 
 

background image

Chöông 4    Quaù taûi haøm  

 

130 

130 

V/ Tìm ñiaï chæ cuûa moät haøm quaù taûi 

 
Trong ngoân ngöõ C, ñeå bieát ñiaï chæ moät haøm, duøng con troû p troû ñeán haøm ñoù, chaúng 
haïn 

p = zap; 

 

// vôùi haøm zap() 

 
Trong ngoân ngöõ C++, vaán ñeà hôi phöùc taïp hôn bôûi vì haøm coù theå ñöôïc quaù taûi. 
 
Cô cheá : duøng caùch khai baùo con troû xaùc ñònh ñiaï chæ cuûa haøm quaù taûi naøo seõ thu 
ñöôïc. 
Haøm coù söï phuø hôïp khai baùo laø haøm coù ñiaï chæ ñöôïc söû duïng. 
 
 
 
Ví duï 5.1 
/* Illustrate assigning function pointers to overloaded functions. */ 
 
#include <iostream.h> 
 
// Output count number of spaces. 
void space(int count)  

  for( ; count; count--)  

cout << ' '; 


 
// Output count number of chs. 
void space(int count, char ch)  

  for( ; count; count--)  

cout << ch; 


 
int main() 

  // Create a pointer to void function with  one int parameter.  
  void (*fp1)(int)
 
  // Create a pointer to void function with one int parameter  

background image

Chöông 4    Quaù taûi haøm  

 

131 

131 

  // and one character parameter.  
  void (*fp2)(int, char)
 
  fp1 = space;  

 

// gets address of space(int) 

  fp2 = space;  

 

// gets address of space(int, char) 

 
  fp1(22);     

// output 22 spaces 

  cout << "|\n"; 
 
  fp2(30, 'x');   

// output 30 xs 

  cout << "|\n"; 
 
  return 0; 

 
 
@ Khai baùo con troû haøm phaûi phuø hôïp chính xaùc vôí moät vaø chæ moät haøm quaù taûi.  
Neáu khoâng, tính khoâng xaùc ñònh seõ xaûy ra vaø gaây ra loãi thôøi gian bieân dòch. 
 
 
 
 
 
Baøi taäp V 
 
 
1. Cho hai haøm quaù taûi. Tìm ñiaï chæ cuûa moãi haøm 
 
int dif(int a, int b) 

  return a-b; 

 
float dif(float a, float b) 

  return a-b; 

background image

Chöông 4    Quaù taûi haøm  

 

132 

132 

Baøi taäp chöông 4 

 

 
1. Haõy quaù taûi haøm taïo date() trong ví duï 1.3, chöông 4  ñeå cho noù nhaän moät tham soá 
kieåu time_t. 
 
2. Tìm loãi sai trong chöông trình sau : 
class samp { 
  int a; 
public: 
  samp(int i) { a = i; } 
  // ... 
}: 
 
// ... 
 
int main() 

  samp x, y(10); 
  // ... 

 
3. Haõy taïo haøm reverse() nhaän hai tham soá. Tham soá thöù nhaát, goïi laø str, laø con troû 
troû tôùi chuoãi maø chuoãi naøy ñöôïc ñaûo ngöôïc khi traû veà töø haøm. Tham soá thöù hai goïi laø 
count vaø noù chæ roõ coù bao nhieâu kyù töï cuûa chuoãi ñeå ñaûo ngöôïc. Haõy cho count moät 
giaù trò maëc ñònh ñeå baùo cho reverse() ñaûo ngöôïc toaøn boä chuoãi. 
 
4. Tìm loãi sai trong ñoaïn chöông trình sau : 
void compute(double *num, int divisor=1); 
void compute(double *num); 
// ... 
compute(&x); 
 
5. Haõy taïo haøm order() ñeå nhaän hai tham soá tham chieáu nguyeân. Neáu ñoái soá thöù nhaát 
lôùn hôn ñoái soá thöù hai, haõy ñaûo ngöôïc hai ñoái soá. Ngöôïc laïi, khoâng taùc ñoäng naøo. Ví 
duï  

 

background image

Chöông 4    Quaù taûi haøm  

 

133 

133 

int x=1, y=0; 
order(x, y); 

 
6. Taïi sao hai haøm quaù taûi sau voán khoâng xaùc ñònh ? 

int f(int a); 
int f(int &a); 

 
7. Cho lôùp sau, haõy boå sung caùc haøm taïo caàn thieát ñeå cho caû hai khai baùo trong 
main() ñeàu ñuùng. 
 
class samp { 
  int a; 
public: 
  // add constructor functions 
   ... 
  int get_a() { return a; } 
}; 
 
int main() 

  samp ob(88);  

// init ob's a to 88 

  samp obarray[10];  

// noninitialized 10-element array 

  // ... 

 
8. Thöïc hieän quaù taûi haøm taïo ñoái vôùi lôùp sau ñaây sao cho caùc ñoái töôïng khoâng ñöôïc 
khôûi ñaàu cuõng ñöôïc taïo ra. 
 
class myclass { 
 

int x, y; 

public : 
 

myclass(int i, int j) {x= i; y =j;} 

 // 

... 


 
9. Qua baøi taäp 8, haõy chöùng toû coù theå khoâng quaù taûi myclass() baèng caùch duøng ñoái soá  
maëc ñònh. 

background image

Chöông 4    Quaù taûi haøm  

 

134 

134 

10. Cho lôùp sau ñaây, coù theå caáp phaùt ñoäng moät maûng caùc ñoái töôïng naøy khoâng ? 
 
class test { 
  char *p; 
  int *q; 
  int count; 
 
public: 
  test(char *x, int *y, int c) { 
    p = x;     q = y;     count = c; 
  } 
  // ... 
 
}; 

background image

 

 

 
 

Chöông 5   
 
 

Quaù taûi toaùn töû 

 
 
 
 
 
 
 

• 

Quaù taûi toaùn töû ñoái vôùi lôùp 

 

• 

Quaù taûi toaùn töû nhò nguyeân 

 

• 

Quaù taûi toaùn töû quan heä & luaän lyù 

 

• 

Quaù taûi toaùn töû ñôn nguyeân 

 

• 

Haøm toaùn töû friend 

 

• 

Toaùn töû gaùn 

 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

136 

136 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

137 

137 

I/ Quaù taûi toaùn töû 

(operator overloading)

 

Quaù taûi toaùn töû 

gioáng nhö quaù taûi haøm. Thöïc chaát quaù taûi toaùn töû chæ laø moät loaïi quaù 

taûi haøm. Moät toaùn töû thöôøng ñöôïc quaù taûi ñoái vôùi moät lôùp.  
 
Khi moät toaùn töû ñöôïc quaù taûi, toaùn töû ñoù khoâng maát yù nghóa goác cuûa noù. Theâm nöõa, 
toaùn töû coøn coù theâm yù nghiaõ boå sung ñoái vôùi lôùp maø toaùn töû ñöôïc ñònh nghiaõ.  
 
 

• 

Ñeå quaù taûi moät toaùn töû, haõy taïo ra moät haøm toaùn töû (operator function). Thoâng 

thöôøng, moät haøm toaùn töû laø moät thaønh vieân (member) hoaëc baïn (friend) cuûa lôùp 
maø toaùn töû ñöôïc ñònh nghiaõ. 

 
Cuù phaùp 
 

return_type  class_name::operator#(arg_list)  

 { 
 

 

// operation to be performed 

 
return_type   kieåu traû veà cuûa moät haøm toaùn töû coù theå laø baát kyø,  

thöôøng laø lôùp maø toaùn töû ñöôïc ñònh nghiaõ 

class_name  teân lôùp chöùa haøm toaùn töû 
#  

ñaïi dieän cho toaùn töû ñöôïc quaù taûi 

arg_list 

danh saùch caùc ñoái soá, thay ñoåi phuï thuoäc vaøo caùch maø haøm toaùn töû  
ñöôïc thöïc hieän vaø kieåu toaùn töû ñöôïc quaù taûi 

 

• 

Hai haïn cheá khi quaù taûi toaùn töû : 

+ thöù tuï öu tieân cuûa caùc toaùn töû khoâng thay ñoåi 
+ soá toaùn haïng cuûa moät toaùn töû khoâng thay ñoåi 

 
Haàu heát caùc toaùn töû trong C++ coù theå ñöôïc quaù taûi. 
Moät soá toaùn töû khoâng theå quaù taûi nhö :   ::  ,  .  ,  *  ,  ? 
Cuõng khoâng theå quaù taûi toaùn töû tieàn xöû lyù. 
 
Hai toaùn töû ñöôïc quaù taûi ">>"  vaø "<<" , duøng ñeå thöïc hieän caùc thao taùc nhaäp/xuaát 
trong C++ 
 

• 

Caùc haøm toaùn töû coù theå khoâng coù caùc ñoái soá  ngaàm ñònh. 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

138 

138 

II/ Quaù taûi toaùn töû nhò nguyeân 

 
Khi moät haøm toaùn töû thaønh vieân quaù taûi toaùn töû nhò nguyeân, haøm seõ chæ coù moät tham 
soá. Tham soá naøy seõ nhaän ñoái töôïng naèm beân phaûi toaùn töû. Ñoái töôïng beân traùi laø ñoái 
töôïng taïo ra lôøi goïi. Goïi cho haøm toaùn töû vaø ñöôïc truyeàn bôûi con troû this . 
 
Caùc haøm toaùn töû ñöôïc vieát theo nhieàu caùch khaùc nhau. 
 

• 

Quaù taûi toaùn töû  "+" ñoái vôùi moät lôùp 

 
Ví duï 2.1 
// Overload the + relative to coord class. 
#include <iostream.h> 
 
class coord { 
  int x, y;  

// coordinate values 

public: 
  coord() { x=0; y=0; } 
  coord(int i, int j) { x=i; y=j; } 
  void get_xy(int &i, int &j) { i=x; j=y; } 
  coord operator+(coord ob2)
}; 
 
// Overload + relative to coord class. 
coord coord::operator+(coord ob2) 

  coord temp; 
  temp.x = x + ob2.x; 
  temp.y = y + ob2.y; 
 
  return temp

 
int main() 

  coord o1(10, 10), o2(5, 3), o3; 
  int x, y; 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

139 

139 

  o3 = o1 + o2;  

// add two objects - this calls operator+() 

  o3.get_xy(x, y); 
  cout << "(o1+o2) X: " << x << ", Y: " << y << "\n"; 
 
  return 0; 

 
@ Khi traû veà moät ñoái töôïng, toaùn töû pheùp "+" cho pheùp moät chuoåi pheùp coäng, ví duï 

o3 = o1 + o2 + o1 + o3; 

 
@ Vì ñoái töôïng coord ñöôïc traû veà, caâu leänh sau ñaây cuõng hoaøn toaøn ñuùng 

(o1 + o2).get_xy(x, y); 

 
 

• 

Quaù taûi toaùn töû  "-" , "=" ñoái vôùi moät lôùp 

 
Ví duï 2.2 
// Overload the +, -, and = relative to coord class. 
#include <iostream.h> 
 
class coord { 
  int x, y; // coordinate values 
public: 
  coord() { x=0; y=0; } 
  coord(int i, int j) { x=i; y=j; } 
  void get_xy(int &i, int &j) { i=x; j=y; } 
  coord operator+(coord ob2); 
  coord operator-(coord ob2)
  coord operator=(coord ob2)
}; 
 
// Overload + relative to coord class. 
coord coord::operator+(coord ob2) 

  coord temp; 
 
  temp.x = x + ob2.x; 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

140 

140 

  temp.y = y + ob2.y; 
  return temp; 

// Overload - relative to coord class. 
coord coord::operator-(coord ob2) 

  coord temp; 
 
  temp.x = x - ob2.x
  temp.y = y - ob2.y
 
  return temp

 
// Overload = relative to coord. 
coord coord::operator=(coord ob2) 

  x = ob2.x; 
  y = ob2.y; 
 
  return *this;  

 

// return the object that is assigned 


 
int main() 

  coord o1(10, 10), o2(5, 3), o3; 
  int x, y; 
 
  o3 = o1 + o2;  

// add two objects - this calls operator+() 

  o3.get_xy(x, y); 
  cout << "(o1+o2) X: " << x << ", Y: " << y << "\n"; 
 
  o3 = o1 - o2;  

 

// subtract two objects 

  o3.get_xy(x, y); 
  cout << "(o1-o2) X: " << x << ", Y: " << y << "\n"; 
 
  o3 = o1;    

// assign an object 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

141 

141 

  o3.get_xy(x, y); 
  cout << "(o3=o1) X: " << x << ", Y: " << y << "\n"; 
 
  return 0; 

@ Vôùi haøm operator-() thöù töï cuûa caùc toaùn haïng laø quan troïng. Do A-B seõ khaùc B-A 

Vì chính toaùn haïng beân traùi taïo ra lôøi goïi ñoái vôùi operator-() neân pheùp tröø phaûi 
theo thöù töï :  

x - ob2.x ; 

 
@ Vôùi haøm toaùn töû gaùn 
 

+ toaùn haïng beân traùi (nghiaõ laø ñoái töôïng ñöôïc gaùn cho moät giaù trò)  
   ñöôïc thay ñoåi bôûi pheùp toaùn. 
+ haøm operator=() traû veà con troû this, nghiaõ laø haøm traû veà ñoái töôïng  
   seõ ñöôïc gaùn. Do ñoù caâu leänh sau cuõng hoaøn toaøn ñuùng : 

o3 = o2 = o1; 

 
 

• 

Coù theå quaù taûi moät toaùn töû ñoái vôùi moät lôùp ñeå cho toaùn haïng beân phaûi laø moät ñoái 

töôïng coù kieåu ñònh saün.

 Toaùn töû "+" ñöôïc quaù taûi ñeå coäng moät giaù trò nguyeân vaø 

ñoái töôïng coord. 

 
Ví duï 2.3 
// Overload +  for ob + int  as well as  ob + ob. 
#include <iostream.h> 
 
class coord { 
  int x, y;  

// coordinate values 

public: 
  coord() { x=0; y=0; } 
  coord(int i, int j) { x=i; y=j; } 
  void get_xy(int &i, int &j) { i=x; j=y; } 
  coord operator+(coord ob2);    

// ob + ob 

  coord operator+(int i);    

 

// ob + int 

}; 
 
// Overload + relative to coord class. 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

142 

142 

coord coord::operator+(coord ob2) 

  coord temp; 
 
  temp.x = x + ob2.x; 
  temp.y = y + ob2.y; 
  return temp; 

// Overload + for ob + int 
coord coord::operator+(int i) 

  coord temp; 
 
  temp.x = x + i
  temp.y = y + i
 
  return temp; 

 
 
int main() 

  coord o1(10, 10), o2(5, 3), o3; 
  int x, y; 
 
  o3 = o1 + o2;  

// add two objects - this calls operator+(coord) 

 
  o3.get_xy(x, y); 
  cout << "(o1+o2) X: " << x << ", Y: " << y << "\n"; 
 
  o3 = o1 + 100;  

// add object + int - this call  operator+(int) 

 
  o3.get_xy(x, y); 
  cout << "(o1+100) X: " << x << ", Y: " << y << "\n"; 
 
  return 0; 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

143 

143 

@ Caàn nhôù, khi quaù taûi moät haøm toaùn töû thaønh vieân ñeå cho moät ñoái töôïng coù theå 
ñöôïc duøng trong moät pheùp toaùn coù kieåu ñònh saün, thì kieåu ñònh saün phaûi ôû beân phaûi 
cuûa toaùn töû. Bôûi vì chính ñoái töôïng beân traùi taïo ra lôøi goïi cho haøm toaùn töû. 
 
 

Ñieàu gì xaûy ra cho caâu leänh naøy ? 

 
o3 = 100 + o1;   

// int + ob 

 

• 

Coù theå duøng tham soá qui chieáu trong moät haøm toaùn töû 

 
Ví duï 2.4 
// Overload + relative to coord class using references. 
coord coord::operator+(coord &ob2

  coord temp; 
 
  temp.x = x + ob2.x; 
  temp.y = y + ob2.y; 
 
  return temp; 

 
 
@ Caùc lyù do phaûi duøng tham soá qui chieáu trong haøm toaùn töû : 

+ Söï hieäu quaû.  Do vieäc truyeàn ñiaï chæ cuûa moät ñoái töôïng thöôøng nhanh hôn vaø     
caûi thieän naêng xuaát so vôùi truyeàn caùc ñoái töôïng nhö caùc tham soá cho haøm. 
 

     + Traùnh nhöõng raéc roái gaây ra khi baûn sao moät toaùn haïng bò huûy. Tuy nhieân, coù theå     
ñònh nghiaõ moät haøm huûy baûn sao ñeå ngaên ngöøa vaán ñeà naøy trong tröôøng hôïp toång 
quaùt. 
 
 
Baøi taäp II 
 
1. Haõy taïo quaù taûi toaùn töû "*" vaø "/" ñoái vôùi lôùp coord. Vieát chöông trình. 
 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

144 

144 

2. Taïi sao phaàn döôùi ñaây laø caùch söû duïng khoâng thích hôïp cuûa moät toaùn töû ñöôïc quaù 
taûi. 
 
coord coord::operator%(coord ob) 

  double i; 
 
  cout << "Enter a number: "; 
  cin >> i; 
  cout << "root of " << i << " is "; 
  cout << sqr(i); 

3. Haõy thöû thay ñoåi caùc kieåu traû veà cuûa caùc haøm toaùn töû ñoái vôùi lôùp khaùc lôùp coord. 
Xem kieåu gì coù keát quûa sai ? 
 
 
 

III/ Quaù taûi caùc toaùn töû quan heä vaø luaän lyù 

Khi quaù taûi caùc toaùn töû quan heä vaø luaän lyù ñeå chuùng hoaït ñoäng theo caùch truyeàn 
thoáng, seõ khoâng caàn caùc haøm toaùn töû traû veà moät ñoái töôïng cuûa lôùp, thay vaøo ñoù caùc 
haøm toaùn töû traû veà moät soá nguyeân ñeå chæ ñuùng hay sai
 

• 

Quaù taûi caùc toaùn töû "==" vaø "&&" 

 
Ví duï 3.1 
// Overload the == and && relative to coord class. 
#include <iostream.h> 
 
class coord { 
  int x, y;  

// coordinate values 

public: 
  coord() { x=0; y=0; } 
  coord(int i, int j) { x=i; y=j; } 
 
  void get_xy(int &i, int &j) { i=x; j=y; } 
   
  int operator==(coord ob2)

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

145 

145 

  int operator&&(coord ob2)
}; 
 
// Overload the == operator for coord. 
int coord::operator==(coord ob2) 

  return x==ob2.x && y==ob2.y;  

 
// Overload the && operator for coord. 
int coord::operator&&(coord ob2) 

  return (x && ob2.x) && (y && ob2.y); 

int main() 

  coord o1(10, 10), o2(5, 3), o3(10, 10), o4(0, 0); 
 
  if(o1==o2)  cout << "o1 same as o2\n"; 
  else  cout << "o1 and o2 differ\n"; 
 
  if(o1==o3)  cout << "o1 same as o3\n"; 
  else  cout << "o1 and o3 differ\n"; 
 
  if(o1&&o2)  

cout << "o1 && o2 is true\n"; 

  else  cout << "o1 && o2 is false\n"; 
 
  if(o1&&o4)  

cout << "o1 && o4 is true\n"; 

  else  cout << "o1 && o4 is false\n"; 
 
  return 0; 

 
 
Baøi taäp III 
 
1. Haõy taïo quaù taûi toaùn töû "<" vaø ">" ñoái vôùi lôùp coord. Vieát chöông trình. 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

146 

146 

IV/ Quaù taûi toaùn töû ñôn nguyeân 

 
Quaù taûi toaùn töû ñôn nguyeân töông töï nhö toaùn töû nhò nguyeân ngoaïi tröø chæ coù moät 
toaùn haïng

 
Khi quaù taûi toaùn töû ñôn nguyeân baèng caùch duøng haøm thaønh vieân, thì haøm khoâng coù 
tham soá

. Do chæ coù moät toaùn haïng, neân chính toaùn haïng naøy taïo ra lôøi goïi cho haøm 

toaùn töû. 
 
 

• 

Quaù taûi toaùn töû taêng "++" ñoái vôùi lôùp 

 
Ví duï 4.1 
// Overload ++ relative to coord class. 
#include <iostream.h> 
 
class coord { 
  int x, y; // coordinate values 
 
public: 
  coord() { x=0; y=0; } 
  coord(int i, int j) { x=i; y=j; } 
  void get_xy(int &i, int &j) { i=x; j=y; } 
  coord operator++() ; 
}; 
 
// Overload ++ for coord class. 
coord coord::operator++() 

  x++; 
  y++; 
 
  return *this

 
 
 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

147 

147 

int main() 

  coord o1(10, 10); 
  int x, y; 
 
  ++o1

;  

// increment an object 

 
  o1.get_xy(x, y); 
  cout << "(++o1) X: " << x << ", Y: " << y << "\n"; 
 
  return 0; 

 

• 

Vôùi ñaëc taû môùi cuûa C++ (chuaån ANSI C++), trình bieân dòch coù theå phaân bieät hai 

caâu leänh naøy laø khaùc nhau 

 

++o ;   

// prefix  - töông öùng vôùi caùch khai baùo ôû ví duï 4.1 

 o++ 

 // 

posfix 

Daïng thöù hai ñöôïc khai baùo nhö sau 

coord coord::operator++(int  notused) ;   

vôùi  notused  luoân luoân ñöôïc truyeàn giaù trò 0. 

 
 

• 

Vôùi daáu tröø "-", vöøa laø toaùn töû nhò nguyeân laãn ñôn nguyeân trong C++. Laøm caùch 

naøo coù theå quaù taûi noù sao cho vaãn giöõ ñöôïc caû hai tính chaát naøy ñoái vôùi lôùp  do 
laäp trình vieân taïo ra ?  
 
Giaûi phaùp : chæ caàn quaù taûi noù hai laàn, moät laàn nhö toaùn töû nhò nguyeân vaø moät laàn 
nhö toaùn töû ñôn nguyeân. 
 

Ví duï 4.2 
// Overload the - relative to coord class. 
#include <iostream.h> 
 
class coord { 
  int x, y; // coordinate values 
public: 
  coord() { x=0; y=0; } 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

148 

148 

  coord(int i, int j) { x=i; y=j; } 
  void get_xy(int &i, int &j) { i=x; j=y; } 
 
  coord operator-(coord ob2);   // binary minus 
  coord operator-();  

 

// unary minus 

}; 
 
 
// Overload - relative to coord class. 
coord coord::operator-(coord ob2) 

  coord temp; 
 
  temp.x = x - ob2.x; 
  temp.y = y - ob2.y; 
 
  return temp

 
// Overload unary - for coord class. 
coord coord::operator-() 

  x = -x; 
  y = -y; 
 
  return *this

 
int main() 

  coord o1(10, 10), o2(5, 7); 
  int x, y; 
 
  o1 = o1 - o2;  

 

// subtraction 

 
  o1.get_xy(x, y); 
  cout << "(o1-o2) X: " << x << ", Y: " << y << "\n"; 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

149 

149 

  o1 = - o1;    

// negation 

 
  o1.get_xy(x, y); 
  cout << "(-o1) X: " << x << ", Y: " << y << "\n"; 
 
  return 0; 

 
 
Baøi taäp IV 
 
1. Haõy quaù taûi toaùn töû "--"  ñoái vôùi lôùp coord. Vieát chöông trình cho caû hai daïng ñöùng 
tröôùc vaø ñöùng sau. 
 
2. Haõy quaù taûi toaùn töû "+"  ñoái vôùi lôùp coord ñeå cho noù laø toaùn töû nhò nguyeân laãn toaùn 
töû ñôn nguyeân. Vieát chöông trình cho caû hai daïng, khi ñöôïc duøng nhö toaùn töû ñôn 
nguyeân haõy thöïc hieän moät giaù trò toaï ñoä aâm baát kyø thaønh döông. 
 
 
 

V/ Haøm toaùn töû friend 

 
Coù theå quaù taûi moät toaùn töû ñoái vôùi lôùp baèng caùch duøng haøm friend, neân nhôù haøm 
friend khoâng coù con troû this.  
 
Vôùi caùc toaùn töû nhò nguyeân, haøm toaùn töû friend ñöôïc truyeàn caû hai toaùn haïng
Vôùi caùc toaùn töû ñôn nguyeân, haøm toaùn töû friend ñöôïc truyeàn moät toaùn haïng
 
Khoâng theå duøng haøm friend ñeå quaù taûi toaùn töû gaùn. 
 
 

• 

Quaù taûi toaùn töû "+" baèng caùch duøng haøm friend 

 
 
 
 
 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

150 

150 

Ví duï 5.1 
// Overload the + relative to coord class using a friend. 
#include <iostream.h> 
 
class coord { 
  int x, y; // coordinate values 
public: 
  coord() { x=0; y=0; } 
  coord(int i, int j) { x=i; y=j; } 
  void get_xy(int &i, int &j) { i=x; j=y; } 
  friend coord operator+(coord ob1, coord ob2)

}; 
 
// Overload + using a friend. 
coord operator+(coord ob1, coord ob2) 

  coord temp; 
 
  temp.x = ob1.x + ob2.x; 
  temp.y = ob1.y + ob2.y; 
 
  return temp

 
int main() 

  coord o1(10, 10), o2(5, 3), o3; 
  int x, y; 
 
  o3 = o1 + o2;  

// add two objects - this calls operator+() 

 
  o3.get_xy(x, y); 
  cout << "(o1+o2) X: " << x << ", Y: " << y << "\n"; 
 
  return 0; 

 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

151 

151 

@ Toaùn haïng beân traùi ñöôïc truyeàn cho tham soá thöù nhaát, toaùn haïng beân phaûi ñöôïc 
truyeàn cho tham soá thöù hai. 
 
 

• 

Quaù taûi moät toaùn töû baèng caùch duøng moät friend cung caáp ñaëc ñieåm quan troïng 

maø moät haøm thaønh vieân khoâng theå coù ñöôïc. Vôùi haøm toaùn töû friend, coù theå ñeå 
cho nhöõng ñoái töôïng ñöôïc söû duïng trong caùc pheùp toaùn coù caùc kieåu ñònh saün, ôû 
ñoù kieåu ñònh saün naèm ôû beân traùi toaùn töû

 

Trong ví duï 2.3, chöông 5, haøm toaùn töû thaønh vieân ñöôïc quaù taûi  

coord coord::operator+(int i) 

 

caâu leänh 

 

ob1 = ob2 + 100;  laø ñuùng 

coøn caâu leänh  

ob1 = 100 + ob2;  laø sai 

 

Vôùi haøm toaùn töû friend, coù theå ñònh nghiaõ haøm quaù taûi sao cho toaùn haïng beân 
traùi laø moät ñoái töôïng vaø toaùn haïng beân phaûi laø kieåu ñònh saün. Sau ñoù, quaù taûi 
toaùn töû naøy laàn nöõa vôùi toaùn haïng beân traùi laø kieåu ñònh saün vaø toaùn haïng beân 
phaûi laø moät ñoái töôïng. 

 
Ví duï 5.2 
// Use friend operator functions to add flexibility. 
#include <iostream.h> 
 
class coord { 
  int x, y; // coordinate values 
 
public: 
  coord() { x=0; y=0; } 
  coord(int i, int j) { x=i; y=j; } 
  void get_xy(int &i, int &j) { i=x; j=y; } 
  friend coord operator+(coord ob1, int i); 
  friend coord operator+(int i, coord ob1); 
}; 
 
 
 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

152 

152 

// Overload for ob + int. 
coord operator+(coord ob1, int i

  coord temp; 
 
  temp.x = ob1.x + i; 
  temp.y = ob1.y + i; 
 
  return temp; 

 
// Overload for int + ob. 
coord operator+(int i, coord ob1

  coord temp; 
 
  temp.x = ob1.x + i; 
  temp.y = ob1.y + i; 
 
  return temp; 

 
int main() 

  coord o1(10, 10); 
  int x, y; 
 
  o1 = o1 + 10; // object + integer 
  o1.get_xy(x, y); 
  cout << "(o1+10) X: " << x << ", Y: " << y << "\n"; 
 
  o1 = 99 + o1; // integer + object 
  o1.get_xy(x, y); 
  cout << "(99+o1) X: " << x << ", Y: " << y << "\n"; 
 
  return 0; 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

153 

153 

@ Do ñoù hai caâu leänh naøy luùc naøy hoaøn toaøn ñuùng 

ob1 = ob2 + 100; 
ob1 = 100 + ob2; 

 
 

• 

Baèng caùch truyeàn toaùn haïng cho friend nhö moät tham soá tham chieáu, nhöõng 

thay ñoåi xaûy ra beân trong haøm friend coù aûnh höôûng ñeán ñoái töôïng taïo ra lôøi goïi. 
Quaù taûi toaùn töû "++" baèng caùch duøng haøm friend. 

 
Ví duï 5.3 
// Overload the ++ using a friend. 
#include <iostream.h> 
 
class coord { 
  int x, y; // coordinate values 
public: 
  coord() { x=0; y=0; } 
  coord(int i, int j) { x=i; y=j; } 
  void get_xy(int &i, int &j) { i=x; j=y; } 
  friend coord operator++(coord &ob)
}; 
 
// Overload ++ using a friend. 
coord operator++(coord &ob) // use reference parameter 

  ob.x++; 
  ob.y++; 
 
  return ob;   // return object generating the call 

 
int main() 

  coord o1(10, 10); 
  int x, y; 
 
  ++o1 ;   

// o1 is passed by reference 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

154 

154 

  o1.get_xy(x, y); 
  cout << "(++o1) X: " << x << ", Y: " << y << "\n"; 
 
  return 0; 

 
@ Neáu duøng trình bieân dòch môùi (theo chuaån ANSI C++), coù theå phaân bieät giöõa caùc 
daïng ñöùng tröôùc vaø ñöùng sau cuûa caùc toaùn töû taêng hay giaûm khi duøng haøm toaùn töû 
friend. Chæ caàn boå sung tham soá nguyeân notused  khi ñònh nghiaõ daïng ñöùng sau 
(nghiaõ laø toaùn töû "++" ñöùng sau toaùn haïng) . 
 

coord operator++(coord &ob);    

 

// prefix 

 

++O 

coord operator++(coord &ob, int notused);   // postfix 

 

O++ 

 
 
Baøi taäp V 
 
1. Haõy quaù taûi toaùn töû "-" vaø "/"  ñoái vôùi lôùp coord duøng haøm friend. Vieát chöông 
trình. 
 
2. Quaù taûi lôùp coord ñeå söû duïng caùc ñoái töôïng coord trong caùc pheùp toaùn maø moät giaù 
trò nguyeân ñöôïc nhaân vôùi moãi toaï ñoä, cho pheùp caùc pheùp toaùn duøng thöù töï cuûa noù : 
 

ob * int 

hoaëc      int * ob 

 
3. Söû duïng friend, haõy quaù taûi toaùn töû "--" ñoái vôùi lôùp coord. Vieát chöông trình cho caû 
hai daïng ñöùng tröôùc vaø sau. 
 
  
 
 
 
 
 
 
 
 
 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

155 

155 

VI/ Toaùn töû gaùn 

Theo maëc ñònh, khi moät toaùn töû gaùn ñöôïc aùp duïng cho moät ñoái töôïng thì moät baûn sao 
töøng bit ñöôïc ñaët vaøo trong ñoái töôïng beân traùi. 
 
Tuy nhieân, coù nhöõng tröôøng hôïp maø baûn sao töøng bit chính xaùc laø khoâng caàn. Xem 
moät soá ví duï trong chöông 2, nhöõng tröôøng hôïp khi moät ñoái töôïng söû duïng boä nhôù. 
Trong nhöõng tröôøng hôïp naøy, caàn phaûi coù moät pheùp gaùn ñaëc bieät. 

• 

Quaù taûi toaùn töû "=" trong lôùp strtype 

 
Ví duï 6.1 
#include <iostream.h> 
#include <string.h> 
#include <stdlib.h> 
 
class strtype { 
  char *p; 
  int len; 
public: 
  strtype(char *s); 
  ~strtype() {  
     cout << "Freeing " << (unsigned) p << '\n'; 
     delete [] p; 
   } 
  char *get() { return p; } 
  strtype &operator=(strtype &ob); 
}; 
 
strtype::strtype(char *s) 

  int l; 
 
  l = strlen(s)+1; 
 
  p = new char [l]; 
  if(!p) { 
    cout << "Allocation error\n"; 
    exit(1); 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

156 

156 

  } 
  len = l; 
  strcpy(p, s); 

 
// Assign an object. 
strtype &strtype::operator=(strtype &ob) 

  // see if more memory is needed 
  if(len < ob.len) {    

// need to allocate more memory 

    delete [] p; 
    p = new char [ob.len]; 
    if(!p) { 
      cout << "Allocation error\n"; 
      exit(1); 
    } 
  } 
  len = ob.len; 
  strcpy(p, ob.p); 
  return *this
}   
 
int main() 

  strtype a("Hello"), b("There"); 
 
  cout << a.get() << '\n'; 
  cout << b.get() << '\n'; 
 
  a = b;  

// now p is not overwritten 

 
  cout << a.get() << '\n'; 
  cout << b.get() << '\n'; 
 
  return 0; 

 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

157 

157 

@ Coù hai ñaëc ñieåm vôùi haøm operator=() trong ví duï naøy 
 

+ noù coù moät tham soá tham chieáu 

 

+ noù traû veà tham chieáu chöù  khoâng phaûi moät ñoái töôïng 

 
 
Baøi taäp VI 
 
1. Cho khai baùo lôùp döôùi ñaây, haõy theâm vaøo caùc chi tieát ñeå taïo neân moät kieåu maûng 
"an toaøn". Sau ñoù, haõy quaù taûi toaùn töû gaùn ñeå cho boä nhôù ñöôïc caáp phaùt cuûa maûng 
khoâng bò huûy tình côø. 
 
class dynarray { 
  int *p; 
  int size; 
public: 
  dynarray(int s);   // pass size of array in s 
  int &put(int i);  

// return reference to element i 

  int get(int i);   

// return value of element i 

  // create operator=() function 
   ... 
}; 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

158 

158 

Baøi taäp chöông 5 

 
 

 
1. Quaù taûi caùc toaùn töû >> vaø << ñoái vôùi lôùp coord ñeå cho coù caùc kieåu pheùp toaùn sau 
ñaây : 

ob << integer ; 
ob >> integer ; 

Vieát chöông trình laøm cho caùc toaùn töû treân naâng caùc giaù trò x vaø y leân moät ñaïi löôïng 
ñöôïc chiû roõ. 
 
2. Cho lôùp 
class three_d { 
  int x, y, z; 
public: 
  three_d(int i, int j, int k)  
  { 
     x = i; y = j; z = k; 
  } 
  three_d() { x=0; y=0; z=0; } 
  void get(int &i, int &j, int &k) 
  { 
     i = x; j = y; k = z; 
  } 
}; 
Haõy quaù taûi caùc toaùn töû  +, -, ++ vaø -- ñoái vôùi lôùp naøy. Ñoái vôùi caùc toaùn töû taêng vaø 
giaûm chiû quaù taûi theo daïng ñöùng tröôùc. Vieát chöông trình thöïc hieän caùc yeâu caàu sau : 
 
- khai baùo caùc ñoái töôïng :  three_d  o1(6,8,10), o2(3,4,5), o3; 
- thöïc hieän caùc pheùp toaùn :   

o3 = o1 + o2; 

    o3 

o1 

o2; 

 

 

 

 

 

++o1 ;  

 

 

 

 

 

--o1; 

- xuaát noäi dung x, y, z cuûa caùc ñoái töôïng treân. 
 
3. Thöïc hieän laïi baøi taäp 2 döôùi daïng tham soá tham chieáu ñoái vôùi caùc haøm toaùn töû. 
Duøng haøm friend ñoái vôùi caùc toaùn töû taêng vaø giaûm. 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

159 

159 

 
4. Vieát chöông trình thöïc hieän quaù taûi toaùn töû + ñoái vôùi lôùp three_d ñeå cho noù nhaän 
caùc kieåu pheùp toaùn sau :  ob +  double;  

 

double + ob; 

 
5. Vieát chöông trình thöïc hieän quaù taûi caùc toaùn töû  ==, !=, vaø // ñoái vôùi lôùp three_d.  
 
6. Vieát chöông trình taïo lôùp strtype ñeå cho pheùp caùc kieåu toaùn töû sau : 
 

* gheùp chuoåi baèng caùch duøng toaùn töû + 

 

* gaùn chuoåi baèng caùch duøng toaùn töû = 

 

* so saùnh chuoåi baèng caùch duøng caùc toaùn töû > , <  vaø == 

 
coù theå duøng chuoåi coù ñoä daøi coá ñònh. Trong ñoù : 
- moät bieán chuoåi s[80] coù daïng private 
- haøm taïo khoâng ñoái soá, thöïc hieän vieäc khôûi taïo chuoåi s laø NULL 
- haøm taïo coù moät ñoái soá *p, thöïc hieän vieäc cheùp noäi dung chuoåi p cho s 
- haøm char *get()  traû veà giaù trò cuûa chuoåi s 
 
7. Haõy boå sung caùc haøm toaùn töû caàn thieát vaøo chöông trình sau.  
* Toaùn töû quaù taûi + coäng moãi phaàn töû cuûa toaùn haïng.  
* Toaùn töû quaù taûi - tröø phaàn töû toaùn haïng beân traùi vôùi moãi phaàn töû cuûa toaùn haïng beân 
phaûi. 
* Toaùn töû quaù taûi == traû veà giaù trò ñuùng neáu moãi phaàn töû cuûa moãi toaùn haïng laø gioáng 
nhau vaø traû veà giaù trò sai neáu ngöôïc laïi. 
 
#include <iostream> 
 
class array { 
  int nums[10]; 
public: 
  array(); 
  void set(int n[10]); 
  void show(); 
  array operator+(array ob2); 
  array operator-(array ob2); 
  int operator==(array ob2); 
}; 
 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

160 

160 

array::array() 

  int i; 
  for(i=0; i<10; i++) nums[i] = 0; 
}   
 
void array::set(int *n) 

  int i; 
   
  for(i=0; i<10; i++) nums[i] = n[i]; 

 
void array::show() 

  int i; 
 
  for(i=0; i<10; i++)  
    cout << nums[i] << ' '; 
 
  cout << "\n"; 

 
// Fill in operator functions. 
// ... 
 
 
  
int main() 

  array o1, o2, o3; 
 
  int i[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
 
  o1.set(i); 
  o2.set(i); 
 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

161 

161 

  o3 = o1 + o2; 
  o3.show(); 
 
  o3 = o1 - o3; 
  o3.show(); 
 
  if(o1==o2) cout << "o1 equals o2\n"; 
  else cout << "o1 does not equal o2\n"; 
 
  if(o1==o3) cout << "o1 equals o3\n"; 
  else cout << "o1 does not equal o3\n"; 
 
  return 0; 

 
8. Thöïc hieän laïi baøi taäp 7 vôùi quaù taûi caùc toaùn töû baèng caùch duøng haøm friend. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 5     Quaù taûi toaùn töû

 

 

 

162 

162 

 
 

background image

 

 

 
 
Chöông 6   
 
 

Tính keá thöøa  

 
 
 
 
 
 
 
 
 

• 

Giôùi thieäu tính keá thöøa 

 

• 

Ñieàu khieån truy caäp lôùp cô sôû 

 

• 

Söû duïng caùc thaønh vieân ñöôïc baûo veä 

 

• 

Haøm taïo, haøm huûy vaø tính keá thöøa 

 

• 

Tính ña keá thöøa 

 

• 

Lôùp cô sôû aûo 

 
 

 
 
 
 
 
 

background image

Chöông 6    Tính keá thöøa 

 

164 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 6    Tính keá thöøa 

 

165 

I/ Giôùi thieäu tính keá thöøa (inheritance) 

Tính keá thöøa

 laø cô cheá nhôø ñoù moät lôùp coù theå keá thöøa caùc ñaëc ñieåm cuûa moät lôùp khaùc. 

 
Tính keá thöøa hoå trôï khaùi nieäm phaân loaïi theo thöù baäc (hierachical classification) cuûa  
lôùp, ngoaøi ra coøn hoå trôï tính ña hình (polymorphism). 
 

• 

Lôùp cô sôû 

(base class) laø lôùp ñöôïc keá thöøa bôûi moät lôùp khaùc. 

Lôùp daãn xuaát 

(derive class) laø lôùp keá thöøa töø moät lôùp cô sôû. 

 
Lôùp cô sôû 

xaùc ñònh caùc tính chaát maø seõ trôû neân thoâng duïng cho caùc lôùp daãn xuaát. 

Nghiaõ laø lôùp cô sôû hieån thò moâ taû toång quaùt nhaát moät taäp hôïp caùc ñaëc ñieåm.  
 
Moät lôùp daãn xuaát keá thöøa caùc ñaëc ñieåm toång quaùt naøy vaø boå sung theâm caùc tính chaát 
rieâng cuûa lôùp daãn xuaát. 
 
Cuù phaùp khai baùo cho lôùp daãn xuaát 
 

class

  derived_class_name :  access_specifier   base_class_name { 

 

 

// body of class 

} ; 

 
base_class_name   

Teân lôùp cô sôû 

derived_class_name 

Teân lôùp daãn xuaát 

access_specifier

      

chæ ñònh truy caäp bao goàm : publicprivate vaø protected 

 

• 

Töø khoaù public baùo cho trình bieân dòch bieát raèng lôùp cô sôû seõ ñöôïc keá thöøa sao 

cho moïi thaønh vieân chung cuûa lôùp cô sôû cuõng seõ laø caùc thaønh vieân chung cuûa lôùp 
daãn xuaát

. Tuy nhieân, moïi thaønh vieân  rieâng cuûa lôùp cô sôû vaãn coøn rieâng ñoái vôùi noù 

vaø khoâng ñöôïc truy caäp tröïc tieáp bôûi lôùp daãn xuaát. 

 

 

Ví duï 1.1 

// A simple example of inheritance. 
#include <iostream.h.h> 
 
 
 

             

  B 

 

 

             

  D 

 Hình 6.1    Söï keá thöøa ñôn

 

background image

Chöông 6    Tính keá thöøa 

 

166 

// Define base class. 
class base {   

 

 

 

 

  int i; 
public: 
  void set_i(int n); 
  int get_i(); 
}; 
 
// Define derived class. 
class derived : public base { 
  int j; 
public: 
  void set_j(int n); 
  int mul(); 
}; 
 
// Set value i in base. 
void base::set_i(int n) 

  i = n; 

 
// Return value of i in base. 
int base::get_i()   { return i; } 
 
// Set value of j in derived. 
void derived::set_j(int n) 

  j = n; 

 
// Return value of base's i times derived's j. 
int derived::mul() 

  // derived class can call base class public member functions 
  return j * get_i(); 

background image

Chöông 6    Tính keá thöøa 

 

167 

int main() 

  derived ob; 
 
  ob.set_i(10); // load i in base 
  ob.set_j(4);  // load j in derived 
 
  cout << ob.mul();  // displays 40 
 
  return 0; 

 

• 

Moät lôùp cô sôû laø khoâng thuoäc rieâng veà moät lôùp daãn xuaát. Lôùp cô sôû coù theå ñöôïc keá 

thöøa bôûi nhieàu lôùp khaùc

 
Ví duï 1.2

 

Lôùp cô sôû chung Fruit coù 2 lôùp daãn xuaát Apple vaø Orange 

// An example of class inheritance. 
#include <iostream.h.h> 
#include <string.h> 
 
enum  yn  {no, yes}; 
enum color {red, yellow, green, orange}; 
 
void out(enum yn x); 
char *c[] = {"red", "yellow", "green", "orange"}; 
 
// Generic fruit class. 
class fruit { 
// in this base, all elements are public 
public:  
  enum  yn  annual;   
  enum  yn  perennial; 
  enum  yn  tree; 
  enum  yn  tropical; 
  enum  color  clr; 
  char name[40]; 
}; 

background image

Chöông 6    Tính keá thöøa 

 

168 

// Derive Apple class. 
class Apple : public fruit { 
  enum yn cooking; 
  enum yn crunchy; 
  enum yn eating; 
public: 
  void seta(char *n, enum  color  c, enum  yn  ck, enum  yn  crchy, enum  yn  e); 
  void show(); 
}; 
 
// Derive orange class. 
class Orange : public fruit { 
  enum  yn  juice; 
  enum  yn  sour; 
  enum  yn  eating; 
public: 
  void seto(char *n, enum  color  c, enum  yn  j, enum  yn  sr, enum  yn  e); 
  void show(); 
}; 
 
void Apple::seta(char *n, enum  color  c, enum  yn  ck, enum  yn  crchy,  

enum  yn  e) 


  strcpy(name, n); 
  annual = no; 
  perennial = yes; 
  tree = yes; 
  tropical = no; 
  clr = c; 
  cooking = ck; 
  crunchy = crchy; 
  eating = e; 

 
void Orange::seto(char *n, enum  color  c, enum  yn  j, enum  yn  sr, enum  yn  e) 

  strcpy(name, n); 

background image

Chöông 6    Tính keá thöøa 

 

169 

  annual = no; 
  perennial = yes; 
  tree = yes; 
  tropical = yes; 
  clr = c; 
  juice = j; 
  sour = sr; 
  eating = e; 

void Apple::show() 

  cout << name << " apple is: " << "\n"; 
  cout << "Annual: ";   

 

out(annual); 

  cout << "Perennial: ";     

out(perennial); 

  cout << "Tree: ";    

 

out(tree); 

  cout << "Tropical: ";  

 

out(tropical); 

  cout << "Color: " << c[clr] << "\n"; 
  cout << "Good for cooking: ";   out(cooking); 
  cout << "Crunchy: ";   

 

out(crunchy); 

  cout << "Good for eating: ";    out(eating);   

  cout << "\n"; 


 
void Orange::show() 

  cout << name << " orange is: " << "\n"; 
  cout << "Annual: ";   

 

out(annual); 

  cout << "Perennial: ";     

out(perennial); 

  cout << "Tree: ";    

 

out(tree); 

  cout << "Tropical: ";   

 

out(tropical); 

  cout << "Color: " << c[clr] << "\n"; 
  cout << "Good for juice: ";  

out(juice); 

  cout << "Sour: ";     

 

out(sour); 

  cout << "Good for eating: ";    out(eating);    cout << "\n"; 

 
 
 

background image

Chöông 6    Tính keá thöøa 

 

170 

void out(enum yn x) 

  if(x==no)   cout << "no\n"; 
  else  cout << "yes\n"; 

 
int main() 

  Apple a1, a2; 
  Orange o1, o2; 
 
  a1.seta("Red Delicious", red, no, yes, yes); 
  a2.seta("Jonathan", red, yes, no, yes); 
  o1.seto("Navel", orange, no, no, yes); 
  o2.seto("Valencia", orange, yes, yes, no); 
 
  a1.show(); 
  a2.show(); 
 
  o1.show(); 
  o2.show(); 
  return 0; 

 
 

Baøi taäp I 
 
1. Cho lôùp cô sôû sau  

class  area_cl { 
public: 
  double height; 
  double width; 
}; 

 
haõy taïo 2 lôùp daãn xuaát box vaø isosceles keá thöøa lôùp area_cl. Vôùi moãi lôùp haõy taïo 
haøm area() laàn löôït traû veà dieän tích cuûa moät hoäp hay moät tam giaùc caân. Duøng caùc 
haøm taïo ñöôïc tham soá hoaù ñeå khôûi ñaàu height vaø width. 

background image

Chöông 6    Tính keá thöøa 

 

171 

II/ Ñieàu khieån truy caäp lôùp cô sôû 

 
Chæ ñònh truy caäp (access_specifier)  xaùc ñònh caùch maø caùc phaàn töû cuûa lôùp cô sôû 
ñöôïc keá thöøa bôûi lôùp daãn xuaát.  
 

• 

Töø khoaù private chæ ñònh caùc thaønh vieân chung lôùp cô sôû trôû thaønh caùc thaønh 

vieân rieâng cuûa lôùp daãn xuaát, 

nhöng nhöõng thaønh vieân naøy vaãn coøn ñöôïc truy caäp 

bôûi caùc haøm thaønh vieân cuûa lôùp daãn xuaát. 

 
Ví duï 2.1 
#include <iostream.h> 
 
class base { 
  int x; 
public: 
  void setx(int n) { x = n; } 
  void showx() { cout << x << '\n'; } 
}; 
 
// Inherit as public. 
class derived : public base { 
  int y; 
public: 
  void sety(int n) { y = n; } 
  void showy() { cout << y << '\n'; } 
}; 
  
int main() 

  derived ob; 
 
  ob.setx(10);  

 

// access member of base class 

  ob.sety(20);  

 

// access member of derived class 

 
  ob.showx();  

 

// access member of base class 

  ob.showy();  

 

// access member of derived class 

 

background image

Chöông 6    Tính keá thöøa 

 

172 

  return 0; 

 
 
Ví duï 2.2 

Lôùp daãn xuaát khoâng theå truy caäp ñeán caùc thaønh vieân rieâng cuûa lôùp cô 

sôû 
 
class base { 
  int  x; 
public: 
  void setx(int n) { x = n; } 
  void showx() { cout << x << '\n'; } 
}; 
 
// Inherit as public - this has an error! 
class derived : public base { 
  int y; 
public: 
  void sety(int n) { y = n; } 
 
  /* Cannot access private member of base class.  
     x is a private member of base and not available within derived. */ 
  void show_sum() { cout << x + y << '\n'; } // Error! 
  void showy() { cout << y << '\n'; } 
}; 
 
 
Ví duï 2.3 

Lôùp daãn xuaát keá thöøa lôùp cô sôû vôùi chæ ñònh private 

// This program contains an error. 
#include <iostream.h> 
 
class base { 
  int x; 
public: 
  void setx(int n) { x = n; } 
  void showx() { cout << x << '\n'; } 
}; 

background image

Chöông 6    Tính keá thöøa 

 

173 

// Inherit base as private. 
class derived : private base { 
  int y; 
public: 
  void sety(int n) { y = n; } 
  void showy() { cout << y << '\n'; } 
}; 
 
int main() 

  derived ob; 
 
  ob.setx(10);  

 

// ERROR - now private to derived class 

  ob.sety(20);  

 

// access member of derived class - OK 

  ob.showx();  

 

// ERROR - now private to derived class 

  ob.showy();  

 

// access member of derived class - OK 

 
  return 0; 

 
@ Löu yù  

Trong haøm main vaãn coù theå truy caäp caùc thaønh vieân chung cuaû lôùp cô 

sôû 

base  base_ob; 
base_ob.setx(1);   // is legal because base_ob is of type base 

 
 
Ví duï 2.4 

Lôùp daãn xuaát keá thöøa lôùp cô sôû vôùi chæ ñònh private, caùc thaønh vieân vaãn 
coøn ñöôïc truy caäp beân trong lôùp daãn xuaát.  

// This program is fixed. 
#include <iostream.h> 
 
class base { 
  int x; 
public: 
  void setx(int n) { x = n; } 
  void showx() { cout << x << '\n'; } 
}; 

background image

Chöông 6    Tính keá thöøa 

 

174 

// Inherit base as private. 
class derived : private base { 
  int y; 
public: 
  // setx is accessible from within derived 
  void setxy(int n, int m) { setx(n);  

y = m; } 

  // showx is accessible from within derived 
  void showxy() { showx();  

cout << y << '\n'; } 

}; 
 
 int main() 

  derived ob; 
 
  ob.setxy(10, 20);  
  ob.showxy(); 
  return 0; 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 6    Tính keá thöøa 

 

175 

Baøi taäp II 
 
1. Xeùt ñoaïn chöông trình sau 
#include <iostream.h> 
 
class mybase { 
  int a, b; 
public: 
  int c; 
  void setab(int i, int j) { a = i; b = j; } 
  void getab(int &i, int &j) { i = a; j = b; } 
}; 
 
class derived1 : public mybase { 

// ... 

}; 
 
class derived2 : private mybase { 

// ... 

}; 
 
int main() 

  derived1 o1; 
  derived2 o2; 
  int i, j; 
   
  // ... 

 
Trong haøm main() caâu leänh naøo sau ñaây laø hôïp leä : 

A.    o1.getab(i,j) ; 
B.    o2.getab(i,j) ; 
C.    o1.c = 10 ; 
D.    o2.c = 10 ; 

2. Ñieàu gì xaûy ra khi moät thaønh vieân rieâng ñöôïc keá thöøa nhö moät thaønh vieân chung ? 
Ñieàu gì xaûy ra khi noù ñöôïc keá thöøa nhö moät thaønh vieân rieâng ? 

background image

Chöông 6    Tính keá thöøa 

 

176 

III/ Söû duïng caùc thaønh vieân ñöôïc baûo veä (protected members) 

 
Vôùi caùc chæ ñònh truy caäp public vaø private, moät lôùp daãn xuaát khoâng truy caäp ñöôïc 
caùc thaønh vieân rieâng cuûa lôùp cô sôû. Tuy nhieân, seõ coù nhöõng luùc muoán moät thaønh vieân 
cuûa lôùp cô sôû vaãn laø rieâng nhöng vaãn cho pheùp lôùp daãn xuaát truy caäp tôùi noù. 
 

• 

Chæ ñònh truy caäp protected, töông ñöông vôùi chæ ñònh private vôùi moät ngoaïi leä 

duy nhaát laø caùc thaønh vieân ñöôïc baûo veä (protected memberscuûa lôùp cô sôû coù theå 
ñöôïc truy caäp ñoái vôùi caùc thaønh vieân cuûa moät lôùp daãn xuaát töø lôùp cô sôû ñoù. 

 

Beân ngoaøi lôùp cô sôû hoaëc lôùp daãn xuaát, caùc thaønh vieân ñöôïc baûo veä khoâng theå 
ñöôïc truy caäp. 

 
Daïng toång quaùt cuûa khai baùo lôùp : 
 

class

  class_name { 

  // 

private 

members 

protected : 

  // 

protected 

members 

public : 

// public members 

}; 

 
Khi moät thaønh vieân ñöôïc baûo veä cuûa moät lôùp cô sôû ñöôïc keá thöøa bôûi lôùp daãn xuaát vôùi 
chæ ñònh public, noù trôû thaønh thaønh vieân ñöôïc baûo veä cuûa lôùp daãn xuaát.  
 
Neáu lôùp daãn xuaát ñöôïc keá thöøa vôùi chæ ñònh private, thì moät thaønh vieân ñöôïc baûo veä 
cuûa lôùp cô sôû trôû thaønh thaønh vieân rieâng cuûa lôùp daãn xuaát
 
Lôùp cô sôû coù theå ñöôïc keá thöøa vôùi chæ ñònh protected bôûi lôùp daãn xuaát, khi ñoù caùc 
thaønh vieân chung vaø ñöôïc baûo veä cuûa lôùp cô sôû trôû thaønh caùc thaønh vieân ñöôïc baûo veä 
cuûa lôùp daãn xuaát.  
 
Coøn caùc thaønh vieân rieâng cuûa lôùp cô sôû vaãn coøn rieâng ñoái vôùi lôùp cô sôû vaø khoâng 
ñöôïc truy caäp bôûi lôùp daãn xuaát. 
 

background image

Chöông 6    Tính keá thöøa 

 

177 

Ví duï 3.1  

Truy caäp caùc thaønh vieân chung, rieâng vaø ñöôïc baûo veä cuûa lôùp cô sôû 

#include <iostream.h> 
 
class samp { 
  // private by default 
  int a; 
protected:   // still private relative to samp 
  int b; 
public: 
  int c;  
 
  samp(int n, int m) { a = n; b = m; } 
  int geta() { return a; } 
  int getb() { return b; } 
}; 
 
int main() 

  samp ob(10, 20); 
 
  // ob.b = 99;   

Error!   b is protected and thus private 

  ob.c = 30;    

// OK,  c is public 

 
  cout << ob.geta() << ' '; 
  cout << ob.getb() << ' ' << ob.c << '\n'; 
 
  return 0; 

 
 
Ví duï 3.2  

Caùc thaønh vieân ñöôïc baûo veä ñöôïc keá thöøa nhö  thaønh vieân chung 

#include <iostream.h> 
 
class base { 
protected :

   // private to base 

  int a, b;  

// but still accessible by derived 

public: 

background image

Chöông 6    Tính keá thöøa 

 

178 

  void setab(int n, int m) { a = n; b = m; } 
}; 
 
class  derived : public base { 
  int c; 
public: 
  void setc(int n) { c = n; } 
 
  // this function has access to a and b from base 
  void showabc() {  
    cout << a << ' ' << b << ' ' << c << '\n';  
  } 
}; 
 
int main() 

  derived ob; 
 
  // a and b are not accessible here because they are private to both base and 
derived.  
  ob.setab(1, 2);  
  ob.setc(3); 
   
  ob.showabc();  
  return 0; 

 
 
Ví duï 3.3  

Caùc thaønh vieân ñöôïc baûo veä ñöôïc keá thöøa bôûi chæ ñònh protected 

// This program will not compile. 
#include <iostream.h> 
 
class base { 
protected :

   // private to base 

  int a, b;  

// but still accessible by derived 

public: 
 

background image

Chöông 6    Tính keá thöøa 

 

179 

  void setab(int n, int m)  
   { a =  n;  
      b =  m;  
   } 
}; 
 
 
class  derived : protected base {  // inherit  as  protected 
  int c; 
public: 
  void setc(int n) { c = n; } 
 
  // this function has access to a and b from base 
  void showabc() {  
    cout << a << ' ' << b << ' ' << c << '\n';  
  } 
}; 
 
int main() 

  derived ob; 
 
  // ERROR:  setab() is now a protected member of base. 
  ob.setab(1, 2);  

// setab()  is not accessible here. 

  ob.setc(3); 
  ob.showabc();  
 
  return 0; 

 
 
 
 
 
 
 
 

background image

Chöông 6    Tính keá thöøa 

 

180 

Baøi taäp III 
 
1.  Laäp baûng toång keát veà quyeàn truy caäp cuûa lôùp daãn xuaát vôùi söï keá thöøa ñôn 
 
Thuoäc tính thaønh vieân 
trong lôùp cô sôû 

Chæ ñònh truy caäp cuûa lôùp 
daãn xuaát 

Quyeàn truy caäp cuûa lôùp 
daãn xuaát 

Public Public 

Private 
Protected 



Private Public 

Private 
Protected 



Protected Public 

Private 
Protected 



2. Trong baøi taäp II/ 1.  chöông 6, neáu a vaø b beân trong lôùp mybase ñöôïc thöïc hieän trôû 
thaønh nhöõng thaønh vieân ñöôïc baûo veä thay vì caùc thaønh vieân rieâng (theo maëc ñònh) thì 
keát quaû theá naøo ? Taïi sao ? 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 6    Tính keá thöøa 

 

181 

IV/ Haøm taïo, haøm huûy vaø tính keá thöøa 

Lôùp cô sôû, lôùp daãn xuaát hoaëc caû hai coù theå coù caùc haøm taïo vaø/hoaëc haøm huûy. 
 

• 

Khi caû lôùp cô sôû laãn lôùp daãn xuaát coù caùc haøm taïo vaø haøm huûy, caùc haøm taïo ñöôïc 

thi haønh theo thöù töï daãn xuaát. Caùùc haøm huûy ñöôïc thi haønh theo thöù töï ngöôïc laïi. 

 
Cuù phaùp truyeàn ñoái soá töø lôùp daãn xuaát ñeán lôùp cô sôû 

 
 

derived_constructor(arg_list) : base(arg_list) { 
 

// body of derived class constructor 

 
 
Ví duï 4.1 
#include <iostream.h> 
 
class base { 
public: 
  base()   { cout << "Constructing base class \n"; } 
  ~base() { cout << "Destructing base class \n"; } 
}; 
 
class derived : public base { 
public: 
  derived() { cout << "Constructing derived class \n"; }  
  ~derived() { cout << "Destructing derived class \n"; } 
}; 
 
int main() 

  derived o; 
 
  return 0; 

 
 
Giaûi thích keát quaû cuûa chöông trình ? 

background image

Chöông 6    Tính keá thöøa 

 

182 

Constructing base class 
Constructing derived class 
Destructing derived class 
Destructing base class 

 
 
Ví duï 4.2 

Truyeàn moät ñoái soá  cho haøm taïo cuûa lôùp daãn xuaát 

#include <iostream.h> 
 
class base { 
public: 
  base() { cout << "Constructing base class\n"; } 
  ~base() { cout << "Destructing base class\n"; } 
}; 
 
class derived : public base { 
  int j; 
public: 
  derived(int n) {  
    cout << "Constructing derived class\n";  
    j = n; 
  }  
  ~derived() { cout << "Destructing derived class\n"; } 
  void showj() { cout << j << '\n'; } 
}; 
 
int main() 

  derived o(10); 

// truyeàn theo caùch thoâng thöôøng 

 
  o.showj(); 
  return 0; 

 
Keát quaû cuûa chöông trình ? 
 
Ví duï 4.3 

Haøm taïo cuûa lôùp daãn xuaát laãn cuûa lôùp cô sôû nhaän moät ñoái soá,  

background image

Chöông 6    Tính keá thöøa 

 

183 

caû hai söû duïng ñoái soá gioáng nhau  

 
#include <iostream.h> 
 
class base { 
  int i; 
public: 
  base(int n) {  
    cout << "Constructing base class\n";  
    i = n; 
  } 
  ~base() { cout << "Destructing base class\n"; } 
  void showi() { cout << i << '\n'; } 
}; 
 
class derived : public base { 
  int j; 
public: 
  derived(int n) : base(n) {  

 

// pass arg to base class 

    cout << "Constructing derived class\n";  
    j = n; 
  }  
  ~derived() { cout << "Destructing derived class\n"; } 
  void showj() { cout << j << '\n'; } 
}; 
 
int main() 

  derived o(10); 
 
  o.showi(); 
  o.showj(); 
   
  return 0; 

 
Keát quaû cuûa chöông trình ? 

background image

Chöông 6    Tính keá thöøa 

 

184 

 

• 

Trong haàu heát caùc tröôønghôïp, caùc haøm taïo ñoái vôùi lôùp cô sôû vaø lôùp daãn xuaát seõ 

khoâng duøng ñoái soá  gioáng nhau

.  

 
Neáu truyeàn moät hay nhieàu ñoái soá cho moãi lôùp, caàn phaûi truyeàn cho haøm taïo cuûa lôùp 
daãn xuaát taát caû caùc ñoái soá maø caû hai lôùp daãn xuaát vaø lôùp cô sôû caàn ñeán. Sau ñoù lôùp 
daãn xuaát chæ truyeàn cho lôùp cô sôû nhöõng ñoái soá  naøo maø lôùp cô sôû caàn ñeán. 

 
Ví duï 4.4

 

#include <iostream.h> 
 
class base { 
  int i; 
public: 
  base(int n) {  
    cout << "Constructing base class\n";  
    i = n; 
  } 
  ~base() { cout << "Destructing base class\n"; } 
  void showi() { cout << i << '\n'; } 
}; 
 
class derived : public base { 
  int j; 
public: 
  derived(int n, int m) : base(m) {  

 

// pass arg to base class 

    cout << "Constructing derived class\n";  
    j = n; 
  }  
  ~derived() { cout << "Destructing derived class\n"; } 
  void showj() { cout << j << '\n'; } 
}; 
 
int main() 

  derived o(10, 20); 
 

background image

Chöông 6    Tính keá thöøa 

 

185 

  o.showi(); 
  o.showj(); 
 
  return 0; 

 
Keát quaû cuûa chöông trình ? 
 
 

• 

Ñoái vôùi haøm taïo cuûa lôùp daãn xuaát khoâng caàn phaûi nhaän moät soá ñeå truyeàn cho 

lôùp cô sôû. Neáu lôùp daãn xuaát khoâng caàn ñoái soá, noù boû qua ñoái soá  vaø chæ truyeàn 
cho lôùp cô sôû. 

 
Ví duï 4.5 
 
class base { 
  int i; 
public: 
  base(int n) {  
    cout << "Constructing base class\n";  
    i = n; 
  } 
  ~base() { cout << "Destructing base class\n"; } 
  void showi() { cout << i << '\n'; } 
}; 
 
class derived : public base { 
  int j; 
public: 
  derived(int n) : base(n) {  

 

// pass arg to base class 

    cout << "Constructing derived class\n";  
    j = 0; // n not used here 
  }  
  ~derived() { cout << "Destructing derived class\n"; } 
  void showj() { cout << j << '\n'; } 
}; 
Baøi taäp IV 

background image

Chöông 6    Tính keá thöøa 

 

186 

 
1.  Cho ñoaïn chöông trình sau, haõy boå sung haøm taïo cho lôùp myderived. Cho 
myderived truyeàn cho lôùp mybase moät con troû veà moät chuoãi khôûi ñaàu. Haõy cho haøm 
taïo myderived() khôûi ñaàu len vôùi ñoä daøi chuoåi. 
 
#include <iostream.h> 
#include <string.h> 
 
class mybase { 
  char str[80]; 
public: 
  mybase(char *s) { strcpy(str, s); } 
  char *get() { return str; } 
}; 
 
class myderived : public mybase { 
  int len; 
public: 
  // add myderived() here 
  int getlen() { return len; } 
  void show() { cout << get() << '\n'; } 
}; 
 
int main() 

  myderived ob("hello"); 
 
  ob.show(); 
  cout << ob.getlen() << '\n'; 
  
  return 0; 

 
2. Laäp caùc haøm taïo car() vaø truck() trong ñoaïn chöông trình sau. Moãi haøm truyeàn caùc 
ñoái soá thích hôïp cho lôùp vehicle. Ngoaøi ra, cho car() khôûi ñaàu passengers vaø truck() 
khôûi ñaàu loadlimit nhö ñöôïc chæ roõ khi ñoái töôïng ñöôïc taïo ra.  Khai baùo caùc ñoái töôïng 

background image

Chöông 6    Tính keá thöøa 

 

187 

 

car     ob(passengers, wheels, range) ; 

 

truck  ob(loadlimit, wheels, range) ; 

#include <iostream.h> 
 
// A base class for various types of vehicles. 
class vehicle { 
  int num_wheels; 
  int range; 
public: 
  vehicle(int w, int r)  
  { 
    num_wheels = w; range = r; 
  } 
  void showv()  
  { 
    cout << "Wheels: " << num_wheels << '\n'; 
    cout << "Range: " << range << '\n'; 
  } 
}; 
 
class car : public vehicle { 
  int passengers; 
public: 
  // insert car() constructor here 
  void show() 
  { 
    showv(); 
    cout << "Passengers: " << passengers << '\n'; 
  } 
}; 
 
class truck : public vehicle { 
  int loadlimit; 
public: 
  // insert truck() constructor here 
  void show() 
  { 

background image

Chöông 6    Tính keá thöøa 

 

188 

    showv(); 
    cout << "loadlimit " << loadlimit << '\n'; 
  } 
}; 
 
int main() 

  car  c(5, 4, 500); 
  truck  t(30000, 12, 1200); 
 
  cout << "Car: \n"; 
  c.show(); 
  cout << "\nTruck:\n"; 
  t.show(); 
 
  return 0; 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

V/ Tính ña keá thöøa 

 

background image

Chöông 6    Tính keá thöøa 

 

189 

1/ Khaùi nieäm 
 

• 

Coù hai caùch ñeå moät lôùp daãn xuaát keá thöøa hôn moät lôùp . 

Thöù nhaát

, lôùp daãn xuaát ñöôïc duøng nhö moät lôùp cô sôû cho moät lôùp daãn xuaát khaùc, 

taïo ra thöù baäc lôùp nhieàu caáp. Khi ñoù caáp cô sôû goác ñöôïc goïi laø lôùp cô sôû giaùng 
tieáp

 cuûa lôùp cô sôû thöù hai (Hình 6.2) . 

 
 
 
 
 
 
Hình 6.2   Keá thöøa ña möùc  

 

Hình 6.3   Keá thöøa phaân caáp 

 

 (Multi 

level 

Inheritance) 

  (Hierarchical 

Inheritance) 

 
Thöù hai

, lôùp daãn xuaát coù theå keá thöøa tröïc tieáp hôn moät lôùp cô sôû. Tröôøng hôïp naøy, hai 

hay nhieàu lôùp cô sôû ñöôïc keát hôïp ñeå taïo ra lôùp daãn xuaát (Hình 6.4) . 
 
 
 
 
 
 
Hình 6.4     Ña keá thöøa    

 

 

Hình 6.5   Keá thöøa lai 

 

 (Multiple 

Inheritance) 

   (Hybrid 

Inheritance) 

 
 
2/ Tính chaát 

• 

Khi moät lôùp cô sôû ñöôïc duøng ñeå daãn ra moät lôùp maø lôùp naøy laïi ñöôïc duøng laøm 

lôùp cô sôû cho moät lôùp daãn xuaát khaùc, thì caùc haøm taïo cuûa caùc lôùp ñöôïc goïi theo 
thöù töï daãn xuaát

. Cuõng vaäy, taát caû caùc haøm huûy ñöôïc goïi theo thöù töï ngöôïc laïi

 

• 

Khi moät lôùp daãn xuaát keá thöøa tröïc tieáp hôn moät lôùp cô sôû, noù duøng caùch khai 

baùo môû roäng nhö sau : 

 

class

  derived_class_name : access  base1 , access  base2, ..., access  baseN { 

 

 

// body of class 

 B 

 

 

D1 

 

 

D2 

B1 

 

    B2 

 

 

    

  

  

 

    D 

  B 

 

 

 

 

D1 

 D2   D3 

 

D4 

        B  

     

 

 

    

  

D1 

  

 

    D2 

 

        D 

background image

Chöông 6    Tính keá thöøa 

 

190 

 

base1 , base2, ... ,  baseN 

  teân caùc lôùp cô sôû 

access 

   

chæ ñònh truy caäp, coù theå khaùc nhau ñoái vôùi moãi lôùp 

 

Khi nhieàu lôùp cô sôû ñöôïc keá thöøa, caùc haøm taïo ñöôïc thi haønh theo thöù töï töø traùi 
qua phaûi 

maø caùc lôùp cô sôû ñaõ ñöôïc chæ ñònh roõ. Caùc haøm huûy ñöôïc thi haønh 

theo thöù töï ngöôïc laïi

 

• 

Khi moät lôùp keá thöøa nhieàu lôùp cô sôû coù caùc haøm taïo caàn nhieàu ñoái soá, lôùp daãn 

xuaát seõ truyeàn caùc ñoái soá caàn thieát cho caùc haøm taïo naøy baèng caùch duøng daïng 
môû roäng cuûa haøm taïo cuûa lôùp daãn xuaát nhö sau : 

 
derived_constructor(arg_list) : base1(arg_list) , base2(arg_list), ..., baseN(arg_list) { 
 

// body of class 


 
Khi moät lôùp daãn xuaát keá thöøa moät heä thoáng thöù baäc caùc lôùp, moãi lôùp daãn xuaát trong 
chuoãi caùc lôùp naøy phaûi truyeàn cho lôùp cô sôû ñöùng tröôùc caùc tham soá maø lôùp daãn xuaát 
naøy caàn. 
 
 
Ví duï 5.1 
// Multiple Inheritance 
#include <iostream.h> 
 
class B1 { 
  int a; 
public: 
  B1(int x) { a = x; } 
  int geta() { return a; } 
}; 
 
 
 
// Inherit direct base class. 
class D1 : public B1 { 

background image

Chöông 6    Tính keá thöøa 

 

191 

  int b; 
public: 
  D1(int x, int y) : B1(y)   // pass y to B1 
  {      
        b = x;   } 
  int getb() { return b; } 
}; 
 
// Inherit a derived class and an indirect base. 
class D2 : public D1 {  
  int c; 
public: 
  D2(int x, int y, int z) : D1(y, z)  // pass args to D1 
  { 
    c = x; 
  } 
 
// Because bases inherited as public, D2 has access to public elements  
//   of both B1 and D1 
  void show() { 
    cout << geta() << ' ' << getb() << ' '; 
    cout << c << '\n'; 
  } 
}; 
 
int main() 

  D2 ob(1, 2, 3); 
 
  ob.show(); 
  // geta() and getb() are still public here 
  cout << ob.geta() << ' ' << ob.getb() << '\n'; 
  return 0; 

Keát quaû cuûa chöông trình ? 
Ví duï 5.2 

Lôùp daãn xuaát keá thöøa tröïc tieáp hai lôùp cô sôû 

#include <iostream.h> 

background image

Chöông 6    Tính keá thöøa 

 

192 

 
// Create first base class. 
class B1 { 
  int a; 
public: 
  B1(int x) { a = x; } 
  int geta() { return a; } 
}; 
 
// Create second base class. 
class B2 { 
  int b; 
public: 
  B2(int x)   {    b = x;  } 
  int getb() { return b; } 
}; 
 
// Directly inherit two base classes. 
class D : public B1public B2 {  
  int c; 
public: 
  // here, z and y are passed directly to B1 and B2 
  D(int x, int y, int z) : B1(z) , B2(y)  {    c = x;  } 
  // Because bases inherited as public, D has access to public elements  
  //   of both B1 and B2.  
  void show() { 
    cout << geta() << ' ' << getb() << ' '; 
    cout << c << '\n'; 
  } 
}; 
 
int main() 

  D ob(1, 2, 3); 
  ob.show(); 
  return 0; 

background image

Chöông 6    Tính keá thöøa 

 

193 

 
Keát quaû cuûa chöông trình ? 
 
 
 
Ví duï 5.3

 

Minh hoïa thöù töï goïi caùc haøm taïo vaø haøm huûy khi lôùp daãn xuaát  
keá thöøa tröïc tieáp nhieàu lôùp cô sôû.  

#include <iostream.h> 
 
class B1 { 
public: 
  B1() { cout << "Constructing B1\n"; } 
  ~B1() { cout << "Destructing B1\n"; } 
}; 
 
class B2 { 
  int b; 
public: 
  B2() { cout << "Constructing B2\n"; } 
  ~B2() { cout << "Destructing B2\n"; } 
}; 
 
// Inherit two base classes. 
class D : public B1 , public B2 {  
public: 
  D() { cout << "Constructing D\n"; } 
  ~D() { cout << "Destructing D\n"; } 
}; 
 
int main() 

  D ob; 
 
  return 0; 

Giaûi thích keát quaû cuûa chöông trình ? 

Constructing B1 

background image

Chöông 6    Tính keá thöøa 

 

194 

Constructing B2  
Constructing D 
Destructing D  
Destructing B2  
Destructing B1 

 
 
Baøi taäp V 
 
1.  Cho ñoaïn chöông trình sau, haõy khaûo saùt keát quaû cuûa chöông trình ? 
#include <iostream.h> 
 
class A { 
public: 
  A() { cout << "Constructing A\n"; } 
  ~A() { cout << "Destructing A\n"; } 
}; 
 
class B { 
public: 
  B() { cout << "Constructing B\n"; } 
  ~B() { cout << "Destructing B\n"; } 
}; 
 
class C : public A, public B { 
public: 
  C() { cout << "Constructing C\n"; } 
  ~C() { cout << "Destructing C\n"; } 
}; 
 
int main() 

  C  ob; 
  return 0; 

 

background image

Chöông 6    Tính keá thöøa 

 

195 

2. Söû duïng heä thoáng thöù baäc lôùp sau ñaây, haõy laäp haøm taïo cua lôùp C ñeå cho noù khôûi 
ñaàu k vaø truyeàn caùc ñoái soá  cho A() vaø B() 
#include <iostream.h> 
 
class A { 
  int i; 
public: 
  A(int a) { i = a; } 
}; 
 
class B { 
  int j; 
public: 
  B(int a) { j = a; } 
}; 
 
class C : public A, public B { 
  int k; 
public: 
  // Create C() so that it initializes k  and passes arguments to both A() and B()  
     ... 
}; 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

VI/ Lôùp cô sôû aûo (virtual base class) 

background image

Chöông 6    Tính keá thöøa 

 

196 

Khi nhieàu lôùp cô sôû ñöôïc keá thöøa tröïc tieáp bôûi moät lôùp daãn xuaát, toàn taïi moät vaán ñeà : 
xuaát hieän nhieàu baûn sao cuûa lôùp cô sôû cuøng hieän dieän trong ñoái töôïng daãn xuaát. 
Chaúng haïn, xeùt heä thoáng thöù baäc lôùp sau 
 
 
 
 
 
 
 
 
 
Bôøi vì coù hai baûn sao cuûa B trong D3, neân moät tham chieáu ñeán moät thaønh vieân cuûa B 
seõ tham chieáu veà B ñöôïc keá thöøa giaùn tieáp thoâng qua D1 hay tham chieáu veà B ñöôïc 
keá thöøa giaùn tieáp thoâng qua D2 ? 
Ñeå giaûi quyeát tính khoâng roõ raøng naøy, C++ coù moät cô cheá maø nhôø ñoù chæ coù moät baûn 
sao cuûa B ôû trong D3. Ñaëc ñieåm naøy ñöôïc goïi laø lôùp cô sôû aûo
 
Coù theå ngaên chaën ñöôïc hai baûn sao cuûa lôùp cô sôû cuøng hieän dieän trong ñoái töôïng daãn 
xuaát baèng caùch cho lôùp cô sôû ñoù ñöôïc keá thöøa nhö virtual bôûi baát kyø caùc lôùp daãn 
xuaát naøo.   
 
 

• 

Töø khoaù virtual ñöùng tröôùc chæ ñònh truy caäp lôùp cô sôû khi noù ñöôïc keá thöøa bôûi 

moät lôùp daãn xuaát. 

 
Ví duï 6.1 
// This program uses a virtual base class. 
 
#include <iostream.h> 
 
class base { 
public: 
  int i; 
}; 
 
// Inherit base as virtual. 

 B 

 

 B 

 

 

 

  
D1   D2 
 

 
 
 

D3

background image

Chöông 6    Tính keá thöøa 

 

197 

class  derived1 : virtual public base { 
public: 
  int j; 
}; 
 
// Inherit base as virtual, here too. 
class  derived2 : virtual public base { 
public: 
  int k; 
}; 
 
//  Here, derived3 inherits both derived1 and derived2. 
//   However, only one copy of base is present. 
class  derived3 : public derived1, public derived2 { 
public: 
  int product() { return i * j * k; } 
}; 
 
int main() 

  derived3 ob; 
 
  ob.i = 10;   // unambiguous because only one copy present 
  ob.j = 3; 
  ob.k = 5; 
 
  cout << "Product is " << ob.product() << '\n'; 
  return 0; 

 
@ Neáu derived1 vaø derived2 khoâng keá thöøa base nhö moät lôùp aûo thì caâu leänh 

ob.i = 10; 

seõ khoâng roõ raøng vaø seõ taïo ra loãi thôøi gian bieân dòch. 
 
 

• 

Khi moät lôùp cô sôû ñöôïc keá thöøa nhö moät lôùp aûo bôûi moät lôùp daãn xuaát thì lôùp cô 

sôû ñoù vaãn coøn toàn taïi trong lôùp daãn xuaát

 .  

background image

Chöông 6    Tính keá thöøa 

 

198 

 

Qua ví duï 6.1 ñoaïn chöông trình sau vaãn hoaøn toaøn ñuùng 

derived1  ob; 
ob.i = 100; 

 
 

• 

Söï khaùc bieät duy nhaát giöõa lôùp cô sôû thöôøng vôùi lôùp cô sôû aûo xaûy ra khi moät ñoái 

töôïng keá thöøa lôùp cô sôû hôn moät laàn

. Neáu caùc lôùp cô sôû aûo ñöôïc söû duïng thì chæ 

coù moät lôùp cô sôû hieän dieän trong ñoái töôïng. Ngöôïc laïi, nhieàu baûn sao seõ ñöôïc tìm 
thaáy. 

 
 
Baøi taäp VI 
 
1.  Trong ví duï 6.1, boû töø khoaù virtual vaø thöû bieân dòch chöông trình. Khaûo saùt loåi ? 
 
2.  Haõy söûa loãi ñoaïn chöông trình sau 
// A variation on the vehicle hierarchy. But this program contains an error. Fix it.  
// 

Hint :   try compiling it as is and observe the error messages. 

 
#include <iostream.h> 
// A base class for various types of vehicles. 
 
class vehicle { 
  int num_wheels; 
  int range; 
public: 
  vehicle(int w, int r)  
  { 
    num_wheels = w; range = r; 
  } 
 
  void showv()  
  { 
    cout << "Wheels: " << num_wheels << '\n'; 
    cout << "Range: " << range << '\n'; 
  } 

background image

Chöông 6    Tính keá thöøa 

 

199 

}; 
 
enum motor {gas, electric, diesel}; 
 
class motorized : public vehicle { 
  enum motor mtr; 
public: 
  motorized(enum motor m, int w, int r) : vehicle(w, r)  { 
    mtr = m; 
  } 
  void showm() {  
    cout << "Motor: "; 
    switch(mtr) { 
      case gas : cout << "Gas\n"; 
        break; 
      case electric : cout << "Electric\n"; 
        break; 
      case diesel : cout << "Diesel\n"; 
        break; 
    } 
  } 
}; 
 
class road_use : public vehicle { 
  int passengers; 
public: 
  road_use(int p, int w, int r) : vehicle(w, r) 
  { 
    passengers = p; 
  } 
  void showr() 
  { 
    cout << "Passengers: " << passengers << '\n'; 
  } 
}; 
enum steering { power, rack_pinion, manual }; 
 

background image

Chöông 6    Tính keá thöøa 

 

200 

class car : public motorizedpublic road_use { 
  enum steering strng; 
public: 
  car(enum steering s, enum motor m, int w, int r, int p) : 
    road_use(p, w, r), motorized(m, w, r), vehicle(w, r)  { 

    strng = s; 

  } 
 
  void show() { 
    showv();   showr();  

showm(); 

    cout << "Steering: "; 
    switch(strng) { 
      case power : cout << "Power\n"; 
        break; 
      case rack_pinion : cout << "Rack and Pinion\n"; 
        break; 
      case manual : cout << "Manual\n"; 
        break; 
    } 
  } 
}; 
   
int main() 

  car  c(power, gas, 4, 500, 5); 
 
  c.show(); 
 
  return 0; 

 
 
 
 

Baøi taäp chöông 6 

 

background image

Chöông 6    Tính keá thöøa 

 

201 

1. Haõy taïo lôùp cô sôû chung building ñeå löu tröõ soá taàng nhaø maø moät toaø nhaø coù soá 
phoøng vaø soá toång dieän tích döôùi daïng protected. Haõy taïo lôùp daãn xuaát house keá thöøa 
building vaø löu tröõ soá phoøng nguõ vaø phoøng taém. Cuõng vaäy, taïo lôùp daãn xuaát office keá 
thöøa public lôùp building vaø löu tröõ soá bình cöùu hoaû vaø soá maùy ñieän thoaïi. Caû hai lôùp 
daãn xuaát ñeà coù haøm taïo vaø haøm show. Vieát chöông trình thöïc hieän yeâu caàu treân ?  
 
2. Cho ñoaïn chöông trình sau, haõy boå sung caùc chi tieát theo chæ daãn trong caùc lôøi chuù 
giaûi 
#include <iostream.h> 
 
class planet { 
protected: 
  double distance;   // miles from the sun 
  int revolve;   

 

// in days 

public: 
  planet(double d, int r) { distance = d; revolve = r; } 
}; 
 
class earth : public planet { 
  double circumference;   // circumference of orbit 
public: 
    // Create earth(double d, int r). Have it pass the distance and days of revolution 
back   
    //  to planet. Have it compute the circumference of the orbit.  
    //  (Hint :  circumference = 2r*3.1416.) 

   

    //  Create a function called show() that displays the  information.  
}; 
 
int main() 

  earth ob(93000000, 365); 
  ob.show(); 
  return 0; 

3. Cho ñoaïn chöông trình sau, haõy boå sung ñeå chöông trình chaïy toát 
 

background image

Chöông 6    Tính keá thöøa 

 

202 

// Overload the +, -, and = relative to coord class. Then, use coord as a base for 
quad.  
#include <iostream.h> 
 
class coord { 
public: 
  int x, y;  

// coordinate values 

  coord() { x=0; y=0; } 
  coord(int i, int j) { x=i; y=j; } 
  void get_xy(int &i, int &j) { i=x; j=y; } 
  coord operator+(coord ob2); 
  coord operator-(coord ob2); 
  coord operator=(coord ob2); 
}; 
 
// Overload + relative to coord class. 
coord coord::operator+(coord ob2) 

  coord temp; 
 
  cout << "Using coord operator+()\n"; 
 
  temp.x = x + ob2.x; 
  temp.y = y + ob2.y; 
 
  return temp; 

 
// Overload - relative to coord class. 
coord coord::operator-(coord ob2) 

  coord temp; 
  cout << "Using coord operator-()\n"; 
 
  temp.x = x - ob2.x; 
  temp.y = y - ob2.y; 
  return temp; 

background image

Chöông 6    Tính keá thöøa 

 

203 


 
// Overload = relative to coord. 
coord coord::operator=(coord ob2) 

  cout << "Using coord operator=()\n"; 
 
  x = ob2.x; 
  y = ob2.y; 
 
  return *this;  

// return the object that is assigned to 


 
 
class quad : public coord { 
  int quadrant; 
public: 
  quad() { x = 0; y = 0; quadrant = 0; } 
  quad(int x, int y) : coord(x, y)  { 
    if(x>=0 && y>=0)  

quadrant = 1; 

    else if(x<0 && y>=0)   quadrant = 2; 
     

else if(x<0 && y<0)  

quadrant = 3; 

        else  quadrant = 4; 

  } 
  void showq()  {   
     cout << "Point in Quadrant: " << quadrant << '\n';  
  } 
  quad operator=(coord ob2); 
}; 
 
 
quad quad::operator=(coord ob2) 

  cout << "Using quad operator=()\n"; 
 
  x = ob2.x; 
  y = ob2.y; 

background image

Chöông 6    Tính keá thöøa 

 

204 

  if(x>=0 && y>=0) quadrant = 1; 
  else if(x<0 && y>=0) quadrant = 2; 

 else if(x<0 && y<0) quadrant = 3; 

else quadrant = 4; 

  return *this; 

   
 
int main() 

  quad o1(10, 10), o2(15, 3), o3; 
  int x, y; 
 
  o3 = o1 + o2;  

// add two objects - this calls operator+() 

  o3.get_xy(x, y); 
  o3.showq(); 
  cout << "(o1+o2) X: " << x << ", Y: " << y << "\n"; 
 
  o3 = o1 - o2;  

 

// subtract two objects 

  o3.get_xy(x, y); 
  o3.showq(); 
  cout << "(o1-o2) X: " << x << ", Y: " << y << "\n"; 
 
  o3 = o1;    

// assign an object 

  o3.get_xy(x, y); 
  o3.showq(); 
  cout << "(o3=o1) X: " << x << ", Y: " << y << "\n"; 
 
  return 0; 

 
4. Haõy söûa ñoåi chöông trình treân sao cho noù söû duïng caùc haøm toaùn töû friend ? 
 
5. Haõy taïo moät phaân caáp lôùp ñeå löu tröõ thoâng tin veà maùy bay. Haõy baét ñaàu baèng moät 
lôùp cô sôû teân laø airship chöùa thoâng tin veà soá löôïng haønh khaùch toái ña vaø troïng löôïng 
haøng hoaù toái ña (ñôn vò tính laø pound) maø maùy bay coù theå chôû ñöôïc.  
 

background image

Chöông 6    Tính keá thöøa 

 

205 

Taïo hai lôùp daãn xuaát airplane vaø balloons. Lôùp airplane löu kieåu cuûa ñoäng cô (goàm 
ñoäng cô caùnh quaït vaø ñoäng cô phaûn löïc), taàm xa (ñôn vò tính laø mile). Lôùp balloon 
löu thoâng tin veà loaïi nhieân lieäu söû duïng chi khí caàu (goàm hai loaïi laø hydrogen vaø 
helium), ñoä cao toái ña (ñôn vò tính laø feed). Vieát chöông trình minh hoaï hoaït ñoäng 
cuûa chuùng. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

 

 

 
Chöông 7   
 
 

Heä thoáng Nhaäp/Xuaát C++  

 
 
 
 
 
 
 
 
 

• 

Cô sôû Nhaäp/Xuaát C++ 

 

• 

Nhaäp/Xuaát coù ñònh daïng 

 

• 

Söû duïng width(), precision() vaø fill() 

 

• 

Söû duïng boä thao taùc Nhaäp/Xuaát 

 

• 

Taïo boä cheøn 

 

• 

Taïo boä chieát 

 

 
 
 
 
 
 
 
 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

208 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

209 

I/ Cô sôû Nhaäp/Xuaát C++ 

Heä thoáng Nhaäp/Xuaát cuûa C++ cuõng ñieàu khieån caùc stream . 
 

• 

Stream 

laø moät thieát bò logic coù chöùc naêng taïo ra hoaëc söû duïng thoâng tin. Nhôø heä 

thoáng Nhaäp/Xuaát cuûa C++, moãi stream ñöôïc lieân keát vôùi thieát bò vaät lyù. Cho duø coù 
nhieàu loaïi thieát bò vaät lyù khaùc nhau, nhöng caùc stream ñeàu ñöôïc xöû lyù nhö nhau
Chính vì vaäy maø heä thoáng Nhaäp/Xuaát coù theå vaän haønh treân baát kyø loaïi thieát bò 
naøo. 

 
Khi moät chöông trình C++ ñöôïc thöïc thi seõ coù boán stream ñöôïc môû moät caùch töï 
ñoäng. 
 
 

Stream 

YÙ nghiaõ 

Thieát bò maëc ñònh 

 

 cin 

thieát bò nhaäp chuaån 

Baøn phím 

  

 cout 

thieát bò xuaát chuaån 

Maøn hình 

 

 cerr 

thieát bò baùo loãi chuaån 

Maøn hình 

  

 clog 

Phieân baûn cuûa cerr 

Maøn hình 

 
Coù theå ñònh laïi cho caùc stream ñeå lieân keát gaén vôùi caùc thieát bò xuaát nhaäp khaùc. 
 
 

• 

Trong chöông I, C++ cung caáp caùc hoå trôï cho heä thoáng Nhaäp/Xuaát trong file 

iostream.h Noäi dung cuûa file naøy laø caùc phaân caáp lôùp hoå trôï caùc thao taùc 
Nhaäp/Xuaát. C++ coù hai phaân caáp lôùp Nhaäp/Xuaát, chuùng coù lieân heä vôùi nhau 
nhöng chuùng khoâng gioáng nhau. 

 
Phaân caáp lôùp Nhaäp/Xuaát thöù nhaát ñöôïc suy daãn töø lôùp Nhaäp/Xuaát möùc thaáp teân laø 
streambuf

Lôùp naøy cung caáp caùc thao taùc cô baûn cuûa Nhaäp/Xuaát caáp thaáp, cuõng nhö 

caùc hoå trôï cô baûn cho toaøn boä heä thoáng Nhaäp/Xuaát cuûa C++

. Laäp trình vieân trình ñoä 

cao neân söû duïng tröïc tieáp lôùp streambuf naøy. 
 
Phaân caáp lôùp Nhaäp/Xuaát thöù hai coù teân ios , laø lôùp Nhaäp/Xuaát caáp cao. Noù cung caáp 
caùc thao taùc veà ñònh daïng, kieåm loãi, chöùa nhieàu haøm vaø bieán duøng ñeå ñieàu khieån vaø 
kieåm soaùt caùc thao taùc cô baûn cuûa caùc stream Nhaäp/Xuaát. 
 
Lôùp ios laø lôùp cô sôû ñeå suy daãn ra caùc lôùp istreamostream vaø iostream.h. Ba lôùp 
daãn xuaát naøy ñöôïc söû duïng ñeå taïo ra caùc stream Nhaäp, Xuaát vaø Nhaäp/Xuaát. 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

210 

II/ Nhaäp/Xuaát coù ñònh daïng 

 
1/

 Moãi stream cuûa C++ ñöôïc ñi keøm vôùi caùc côø ñònh daïng (format  flags). 

Caùc côø ñònh daïng naøy xaùc ñònh caùch thöùc theå hieän cuûa döõ lieäu, caùc côø ñöôïc maõ hoaù 
döôùi daïng soá nguyeân kieåu long int. Caùc côø ñònh daïng ñöôïc ñaët teân vaø giaù trò trong lôùp 
ios

 qua baûng lieät keâ nhö sau : 

 
// ios format flags 
enum{ 

skipws 

=  0x0001; 

left    

=  0x0002; 

right    

=  0x0004; 

internal 

=  0x0008; 

dec   

=  0x0010; 

oct 

 

=  0x0020; 

hex   

=  0x0040; 

showbase  =  0x0080; 
showpoint  =  0x0100; 
uppercase  =  0x0200; 
showpos 

=  0x0400; 

scientific 

=  0x0800; 

fixed   

=  0x1000; 

unitbuf 

=  0x2000;  

stdio   

=  0x4000; 

}; 
 
Khi moät côø ñònh daïng naøo ñoù ñöôïc thieát laäp thì ñaëc tính cuûa côø ñoù trôû neân coù hieäu 
löïc. Neáu côø ñònh daïng bò xoaù, heä thoáng seõ duøng giaù trò maëc ñònh cho ñaëc tính cuûa côø 
ñoù.  
 
 
2/ Moâ taû caùc côø ñònh daïng

 

 

• 

Khi côø   skipws ñöôïc thieát laäp, caùc kyù töï caùch (goàm caùc kyù töï khoaûng caùch, tab 

vaø xuoáng doøng) ñöôïc boû ñi khi ñoïc moät stream. Neáu côø naøy bò xoaù, caùc kyù töï 
caùch seõ khoâng bò boû ñi. Thöôøng aùp duïng cho moät soá kieåu file treân diaõ. 
 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

211 

• 

Khi côø left ñöôïc thieát laäp, keát xuaát seõ ñöôïc canh bieân traùi. 

• 

Khi côø right ñöôïc thieát laäp, keát xuaát seõ ñöôïc canh bieân phaûi.  

• 

Khi côø internal ñöôïc thieát laäp, daáu cuûa trò soá ñöôïc canh bieân traùi trong khi con 

soá 

ñöôïc canh bieân traùi. Neáu caû ba côø ñeàu bò xoaù, theo maëc ñònh, keát xuaát seõ ñöôïc 

canh bieân phaûi. 
 

• 

Theo maëc ñònh, giaù trò nguyeân ñöôïc trình baøy döôùi daïng soá thaäp phaân. Tuy 

nhieân. coù theå thay ñoåi cô soá cuûa keát xuaát. Thieát laäp côø oct seõ laøm cho keát xuaát 
ñöôïc trình baøy döôùi daïng soá heä baùt phaân. Thieát laäp côø hex keát xuaát laø soá heä thaäp 
luïc. Ñeå traû laïi kieåu soá thaäp phaân, caàn thieát laäp côø dec
 

• 

Khi ñaët côø showbase, cô soá cuûa giaù trò soá ñöôïc trình baøy. 

 

• 

Khi ñaët côø showpoint cho pheùp in daáu chaám thaäp phaân vaø caùc soá khoâng ñi sau 

keøm theo caùc giaù trò kieåu daáu chaám ñoäng. 
 

• 

Theo maëc ñònh, khi moät con soá kieåu soá muõ ñöôïc in ra, chöõ "e" ñöôïc trình baøy ôû 

kieåu chöõ thöôøng. Töông töï, khi in moät giaù trò soá ôû heä thaäp luïc, kyù töï " duøng chæ 
heä thaäp luïc ñöôïc trình baøy ôû kieåu chöõ thöôøng. Khi côø upcase ñöôïc thieát laäp, caùc 
kyù töï noùi treân seõ ñöôïc trình baøy baèng kieåu chöõ in hoa. 
 

• 

Khi ñaët côø showpos laøm cho xuaát hieän daáu coäng phiaù tröôùc caùc giaù trò soá döông. 

 

• 

Khi ñaët côø scientific laøm caùc giaù trò soá kieåu daáu chaám ñoäng ñöôïc trình baøy döôí 

daïng muõ. Nhöng khi ñaët côø fixed, caùc giaù trò soá kieåu daáu chaám ñoäng ñöôïc trình 
baøy döôí daïng thöôøng coù 6 soá leõ.  
 

• 

Khi ñaët côø unitbuf, heä thoáng Nhaäp/Xuaát cuûa C++ ñaåy stream xuaát ra heát sau 

moãi thao taùc xuaát.  
 

• 

Khi ñaët côø stdio, thieát bò xuaát chuaån stdout vaø thieát bò nhaäp chuaån stdin seõ ñöôïc 

ñaåy ra sau moãi thao taùc xuaát. Tuy nhieân côø naøy khoâng ñöôïc ñònh nghiaõ trong 
chuaån truø ñònh ANSI C++, vaø coù theå khoâng aùp duïng trong moät soá trình bieân dòch. 

 
3/ Caùc haøm lieân quan ñeán côø ñònh daïng 
 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

212 

• 

Haøm setf() duøng thieát laäp côø ñònh daïng. Haøm naøy thuoäc lôùp ios. Daïng toång quaùt 


 

 

  long 

 

setf

(long  flags) ; 

 
Haøm traû veà giaù trò ñöôïc thieát laäp tröôùc ñoù cuûa côø vaø thieát laäp caùc côø coù teân trong 
haøm. Ví duï thieát laäp côø showpos : 

stream

.setf(ios::showpos) ; 

 

stream

 laø teân stream caàn ñeå thieát laäp côø showpos  

 
 
Löu y

ù, trong C++, khoâng theå ñaët côø ñònh daïng ôû phaïm vi toaøn cuïc chung cho taát caû 

caùc stream, moãi stream seõ mang moät thoâng tin traïng thaùi caùc ñònh daïng rieâng cuûa noù 
vaø chuùng ñoäc laäp vôùi nhau. 
 
Coù theå goïi haøm setf() ñeå laäp nhieàu côø cuøng luùc, baèng caùch duøng toaùn töû OR. Ví duï  
 

cout

.setf(ios::showbase | ios::hex) ; 

 

• 

Haøm xoaù côø unsetf(), duøng ñeå xoaù moät hay nhieàu côø ñònh daïng. Daïng toång quaùt 


 

 

  long 

 

unsetf

(long  flags) ; 

  Haøm traû veà giaù trò tröôùc ñoù cuûa côø. 
 

• 

Haøm flags() cho bieát traïng thaùi cuûa côø ñònh daïng. Haøm naøy thuoäc lôùp ios. Daïng     

thöôøng goïi : 

 

 

long  flags() ; 

 
Daïng coù keøm ñoái soá   long  flags(long  f) ; 

 
cho pheùp thieát laäp taát caû caùc côø ñònh daïng cuûa stream döïa theo giaù trò cuûa ñoái soá khi 
goïi haøm. Töøng bit cuûa giaù trò f seõ ñöôïc gaùn cho bieán löu trò côø ñònh daïng, vaø seõ xoaù 
tình traïng côø ñònh daïng tröôùc ñoù. Haøm seõ traû veà giaù trò tình traïng caùc côø ñònh daïng 
tröôùc ñoù. 
 
 
 

Ví duï 2.1 

 

Minh hoaï haøm setf() 

#include <iostream.h> 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

213 

 
int main() 

  // display using default settings 
  cout << 123.23 << " hello " << 100 << '\n'; 
  cout << 10 << ' ' << -10 << '\n'; 
  cout << 100.0 << "\n\n"; 
 
  // now, change formats 
  cout.unsetf(ios::dec);   // not required by all compilers 
  cout.setf(ios::hex | ios::scientific); 
  cout << 123.23 << " hello " << 100 << '\n'; 
 
  cout.setf(ios::showpos); 
  cout << 10 << ' ' << -10 << '\n'; 
 
  cout. setf(ios::showpoint | ios::fixed); 
  cout << 100.0; 
  return 0; 

 
Keát quaû cuûa chöông trình 
123.23 hello 100 
10 -10 
100 
 
1.232300e+02 hello 64 
a fffffff6 
+100.000000 
 
 
Ví duï 2.2 

 

Minh hoaï haøm unsetf() 

#include <iostream.h> 
 
 
int main() 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

214 

  cout.unsetf(ios::dec); 
  cout.setf(ios::uppercase | ios::showbase | ios::hex); 
 
  cout << 88 << '\n'; 
 
  cout.unsetf(ios::uppercase); 
 
  cout << 88 << '\n'; 
 
  return 0; 

 
 
Ví duï 2.3 

 

Minh hoaï haøm flags() 

#include <iostream.h> 
 
void showflags(); 
 
int main() 

  // show default condition of format flags 
  showflags(); 
 
  cout.setf(ios::oct | ios::showbase | ios::fixed); 
 
  showflags(); 
 
  return 0;  

 
// This function displays the status of the format flags. 
void showflags() 

  long f
 
  f = cout.flags();    // get flag settings 
   

Keát quaû cuûa chöông trình 
 
0X58 
0x58

 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

215 

  if(f & ios::skipws) cout << "skipws on\n"; 
  else cout << "skipws off\n"; 
 
  if(f & ios::left) cout << "left on\n"; 
  else cout << "left off\n"; 
 
  if(f & ios::right) cout << "right on\n"; 
  else cout << "right off\n"; 
 
  if(f & ios::internal) cout << "internal on\n"; 
  else cout << "internal off\n"; 
 
  if(f & ios::dec) cout << "dec on\n"; 
  else cout << "dec off\n"; 
 
  if(f & ios::oct) cout << "oct on\n"; 
  else cout << "oct off\n"; 
  if(f & ios::hex) cout << "hex on\n"; 
  else cout << "hex off\n"; 
 
  if(f & ios::showbase) cout << "showbase on\n"; 
  else cout << "showbase off\n"; 
 
  if(f & ios::showpoint) cout << "showpiont on\n"; 
  else cout << "showpoint off\n"; 
 
  if(f & ios::showpos) cout << "showpos on\n"; 
  else cout << "showpos off\n"; 
 
  if(f & ios::uppercase) cout << "uppercase on\n"; 
  else cout << "uppercase off\n"; 
 
  if(f & ios::scientific) cout << "scientific on\n"; 
  else cout << "scientific off\n"; 
 
  if(f & ios::fixed) cout << "fixed on\n"; 
  else cout << "fixed off\n"; 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

216 

 
  if(f & ios::unitbuf) cout << "unitbuf on\n"; 
  else cout << "unitbuf off\n"; 
 
  if(f & ios::stdio) cout << "stdio on\n"; 
  else cout << "stdio off\n"; 
 
  cout << "\n"; 

 
Keát quaû cuûa chöông trình 

skipws

 

is on

 

left    

is off 

right    

is off 

internal 

is off  

dec  

is 

off 

oct 

 

is off  

hex   

is off  

showbase  is off  
showpoint  is off  
uppercase is 

off 

showpos 

is off  

scientific 

is off  

fixed   

is off  

unitbuf 

is off  

stdio  

is off 

 

skipws

 

is on

 

left    

is off 

right    

is off 

internal 

is off  

dec  

is 

off 

oct

   

is on 

 

hex   

is off  

showbase

  is on  

showpoint  is off  
uppercase is 

off 

showpos 

is off  

scientific 

is off  

fixed

   

is on 

 

unitbuf 

is off  

stdio  

is off 

 
 
Ví duï 2.4 

Minh hoaï haøm flags(), söû duïng maët naï côø (flag mask) duøng ñeå thieát laäp 

caùc côø showpos, showbase, oct vaø right. Boán côø naøy mang giaù trò töông öùng laø 
0x0400, 0x0080, 0x0020, 0x0004. Coäng boán giaù trò naøy ta coù giaù trò 0x04A4 . 

 
#include <iostream.h> 
void showflags() ; 
 
int main() 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

208 


  // show default condition of format flags 
  showflags(); 
 
  // showpos, showbase, oct, right are on, others off 
  long  f  =  0x04A4; 
 
  cout.flags(f);  // set flags 
 
  showflags(); 
  return 0;  

 
 
 
 
 
Baøi taäp II 
 
1. Haõy vieát chöông trình thieát laäp traïng thaùi caùc côø ñònh daïng, sao cho caùc giaù trò 
nguyeân döông ñöôïc in ra coù mang daáu +. Haõy in ra cho bieát laø caùc côø ñònh daïng ñaõ 
ñöôïc thieát laäp. 
 
2. Haõy vieát chöông trình ñeå thieát laäp traïng thaùi caùc côø ñònh daïng cuûa stream cout sao 
cho caùc giaù trò soá kieåu daáu chaám ñoäng ñöôïc trình baøy vôùi daáu chaám thaäp phaân. Ngoaøi 
ra, caùc giaù trò soá kieåu daáu chaám ñoäng ñöôïc in ra döôùi daïng soá muõ, vôùi kyù töï "E" chæ 
phaàn muõ ñöôïc trình baøy baèng kieåu chöõ in hoa. 
 
3. Haõy vieát chöông trình thöïc hieän chöùc naêng löu laïi traïng thaùi hieän taïi cuûa caùc côø 
ñònh daïng, tieáp ñeán thieát laäp hai côø showbase vaø hex, roài xuaát ra giaù trò 100, cuoái 
cuøng laäp laïi traïng thaùi ban ñaàu cuûa caùc côø traïng thaùi. 
 
 
 
III/ Söû duïng caùc haøm width(), precision() vaø fill() 
 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

209 

Caùc haøm naøy thieát laäp caùc tham soá ñònh daïng goàm : ñoä roäng cuûa tröôøng, ñoä chính xaùc 
vaø kyù töï laáp ñaày. 
 
Haøm int width(int w) ;   vôùi w laø ñoä roäng cuûa tröôøng 
Haøm traû veà ñoä roäng cuûa tröôøng tröôùc ñoù. 
 
Haøm   int precision(int p);    vôùi p laø chính xaùc caàn thieát laäp 
Haøm traû veà giaù trò laø chính xaùc tröôùc ñoù. 
 
Haøm   char fill (char ch);    vôùi ch laø kyù töï laáp ñaày môùi 
Haøm traû veà kyù töï laáp ñaày tröôùc ñoù. 
 
 
Ví duï 3.1 
#include <iostream.h> 
 
int main() 

  cout.width(10);           

// set minimum field width 

  cout << "hello" << '\n';   // right justify by default   

 

 
  cout.fill('%');           

// set fill character 

  cout.width(12);           

// set width 

  cout << "hello" << '\n';   // right justify by default 
 
  cout.setf(ios::left);     

// left justify 

  cout.width(9);           

// set width 

  cout << "hello" << '\n';   // output left justified 
 
  cout.width(12);           

// set width 

  cout.precision(10);        // set 10 digits of precision 
  cout << 123.234567 << '\n';  
 
  cout.width(10);           

// set width 

  cout.precision(3);         // set 3 digits of precision 
  cout << 123.234567 << '\n';  
 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

210 

  return 0; 

 
Keát quaû cuûa chöông trình 
                 hello 
%%%%%%%hello 
hello%%%% 
123.234567%% 
123.234%%% 
 
 
Ví duï 3.2 

  Caùc haøm ñònh daïng Nhaäp/Xuaát cuûa C++ 

// Create a table of square roots and squares. 
#include <iostream.h> 
#include <math.h> 
 
int main() 

  double x; 
 
  cout.precision(4); 
  cout << "x   sqrt(x)     x^2\n\n"; 
 
  for(x = 2.0; x <= 20.0; x++) { 
    cout.width(7); 
    cout << x << "  "; 
    cout.width(7); 
    cout << sqrt(x) << "  "; 
    cout.width(7); 
    cout << x*x << '\n'; 
  } 
  
  return 0; 

 
Baøi taäp III 
 

Keát quaû cuûa chöông trình 
x sqrt(x) 

  x^2 

 
 2 

1.4142 

 

    4 

 3 

1.7321 

 

    9 

 4 

          2 

 

  16  

 5 

2.2361 

 

  25 

... 

... 

 

              ... 

20 4.4721    400 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

211 

1. Haõy vieát chöông trình thieát in ra logarit cô soá töï nhieân vaø logarit cô soá thaäp phaân 
cuûa caùc con soá töø 2 ñeán 100. Ñònh daïng baûng soá sao cho caùc con soá ñöôïc canh bieân 
phaûi vôùi ñoä roäng tröôøng laø 10. Söû duïng ñoä chính xaùc laø 5. 
 
2. Taïo moät haøm mang teân laø :   void center(char *s) ; 
Chöùc naêng cuûa haøm laø canh giöõa moät chuoãi kyù töï treân maøn hình. Ñeå thöïc hieän haøm 
naøy, haõy söû duïng haøm width(). Giaû söû maøn hình coù ñoä roäng 80 coät (vaø ñeå cho ñôn 
giaûn, giaû söû chuoãi kyù töï coù chieàu daøi < 80 kyù töï). 
 
 
IV/  Söû duïng boä thao taùc Nhaäp/Xuaát (I/O Manipulator) 
 
Boä thao taùc Nhaäp/Xuaát

 laø caùc haøm ñaëc bieät söû duïng trong caùc meänh ñeà Nhaäp/Xuaát. 

Caàn phaûi naïp file tieâu ñeà iomanip.h vaøo chöông trình. Caùc boä thao taùc Nhaäp/Xuaát 
chuaån ñöôïc trình baøy trong baûng sau : 
 

Boä thao taùc 

Muïc ñích 

Nhaäp/Xuaát 

dec 

Ñònh daïng döõ lieäu kieåu soá ôû daïng thaäp phaân 

Xuaát 

endl 

Xuaát moät kyù töï xuoáng doøng vaø  
ñaåy stream ra thieát bò vaät lyù 

Xuaát 

ends 

Xuaát moät kyù töï roãng 

Xuaát 

flush 

Ñaåy stream ra thieát bò vaät lyù 

Xuaát 

hex 

Ñònh daïng döõ lieäu kieåu soá ôû daïng thaäp luïc phaân  Xuaát 

oct 

Ñònh daïng döõ lieäu kieåu soá ôû daïng baùt phaân 

Xuaát 

resetiosflags(long f)  Xoùa caùc côø xaùc ñònh trong f 

Nhaäp/Xuaát 

setbase(int base) 

Ñaët cô soá thaønh base 

Xuaát 

setfill(int ch) 

Ñaët ch laøm kyù töï laáp ñaày 

Xuaát 

setiosflags(long f) 

Thieát laäp caùc côø xaùc ñònh trong f 

Nhaäp/Xuaát 

setprecision(int p) 

Ñaët ñoä chính xaùc laø p 

Xuaát 

setw(int w) 

Ñaët ñoä roäng cuûa tröôøng laø w 

Xuaát 

ws 

Boû qua caùc kyù töï caùch (khoaûng caùch, tab, xuoáng 
doøng) 

Nhaäp 

 
 
 
Caùc boä thao taùc coù theå xuaát hieän trong caùc meänh ñeà Nhaäp/Xuaát. Ví duï 

cout << oct << 100 << hex << 100; 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

212 

cout << setw(10) << 100; 

 
Löu yù caùc boä thao taùc Nhaäp/Xuaát chæ coù aûnh höôûng ñeán stream coù teân trong bieåu 
thöùc Nhaäp/Xuaát, caùc boä thao taùc naøy khoâng aûnh höôûng ñeán taát caû caùc stream ñang 
môû. 
 

• 

Söû duïng boä thao taùc Nhaäp/Xuaát laø caùch thöù hai ñeå ñònh daïng thoâng tin trong heä 

thoáng Nhaäp/Xuaát cuûa C++. Trong moät soá tröôøng hôïp, söû duïng boä thao taùc 
Nhaäp/Xuaát deã daøng hôn laø duøng caùc côø vaø haøm ñònh daïng. 

 
Öu ñieåm 

so vôùi caùc haøm ñònh daïng khaùc cuûa ios laø  

+ tính deã söû duïng 
+ maõ chöông trình seõ ngaén goïn hôn. 

 
Neáu muoán thieát laäp moät soá côø ñònh daïng baèng boä thao taùc, haõy duøng setiosflags(). Boä 
thao taùc naøy coù chöùc naêng gioáng nhö haøm setf(). 
 
Neáu muoán xoaù moät soá côø ñònh daïng baèng boä thao taùc, haõy duøng resetiosflags(). Boä 
thao taùc naøy coù chöùc naêng gioáng nhö haøm unsetf(). 
 
 
Ví duï 4.1 

Söû duïng boä thao taùc Nhaäp/Xuaát 

#include <iostream.h> 
#include <iomanip.h
 
int main() 

  cout << hex << 100 << endl;  

// 

64 

  cout << oct << 10 << endl;   // 

12 

 
  cout << setfill('X') << setw(10)
  cout << 100 << " hi " << endl;   

// XXXXXXX144 hi 

  return 0; 

 
 Ví duï 4.2 

 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

213 

// This version uses I/O manipulators to display the table of squares and square 
roots.  
 
#include <iostream.h> 
#include <iomanip.h
#include <math.h> 
 
int main() 

  double x; 
 
  cout << setprecision(4)
  cout << "      x   sqrt(x)     x^2\n\n"; 
 
  for(x = 2.0; x <= 20.0; x++) { 
    cout << setw(7) << x << "  "; 
    cout << setw(7) << sqrt(x) << "  "; 
    cout << setw(7) << x*x << '\n'; 
  } 
  
  return 0; 

 
 
Baøi taäp IV 
 
1. Thöïc hieän caùc baøi taäp 1 vaø 2 cuûa phaàn III chöông 7, trong ñoù haõy söû duïng caùc boä 
thao taùc Nhaäp/Xuaát thay cho haøm ñònh daïng. 
 
2. Vieát moät chöông trình nhoû xuaát giaù trò 100 ôû daïng soá thaäp luïc phaân coù keøm theo 
kyù töï chæ heä thaäp luïc (0x). Haõy söû duïng boä thao taùc setiosflags(). 
 
 

 
 
V. Taïo boä cheøn vaøo (inserter) 

Keát quaû chöông trình 
x sqrt(x) 

  x^2 

 

1.4142 

  4 

1.7321 

  9 

         2  

16 

5 2.2361  25 
...

 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

214 

 
Quaù taûi toaùn töû Nhaäp/Xuaát cho caùc lôùp töï taïo laø moät trong nhöõng lyù do quyeát ñònh söû 
duïng meänh ñeà Nhaäp/Xuaát cuûa C++ thay cho vieäc söû duïng caùc haøm Nhaäp/Xuaát theo 
kieåu C. 
 

• 

Theo C++, thao taùc xuaát coøn ñöôïc goïi laø cheøn (insert), toaùn töû << coøn goïi laø 

toaùn töû cheøn. 

Khi quaù taûi toaùn töû naøy, nghiaõ laø taïo moät haøm cheøn, hay coøn goïi laø 

boä cheøn 

(inserter) , do toaùn töû << thöïc hieän chöùc naêng cheøn thoâng tin vaøo trong 

moät stream. 

 
Cuù phaùp caùc boä cheøn 
 

ostream

 &operator << (ostream &stream, class_name ob) 

 { 
 

 

// body of inserter 

 
stream : tham soá thöù nhaát tham chieáu ñeán moät ñoái töôïng thuoäc kieåu ostream.  

  Stream stream phaûi laø moät stream xuaát 

ob 

: tham soá thöù hai laø ñoái töôïng caàn xuaát (noù coù theå laø moät tham chieáu) 

 
Boä cheøn seõ traû veà moät tham chieáu ñeán stream stream kieåu ostream. Ñieàu naøy caàn 
thieát khi söû duïng toaùn töû << trong caùc bieåu thöùc Nhaäp/Xuaát phöùc taïp, ví duï 
 

cout << ob1 << ob2 << ob2; 

 
Noäi dung cuûa boä cheøn

 coù theå thöïc hieän baát kyø thuû tuïc naøo maø laäp trình vieân muoán. 

Kinh nghieäm cho bieát, neân giôùi haïn chöùc naêng cuûa noù trong phaïm vi keát xuaát thoâng 
tin ra moät stream. 
 
 

• 

Moät boä cheøn khoâng ñöôïc pheùp laø thaønh phaàn cuûa lôùp maø boä cheøn naøy thao taùc. 

Lyù do, khi moät haøm toaùn töû kieåu baát kyø laø moät thaønh phaàn cuûa moät lôùp naøo ñoù, toaùn 
haïng beân traùi voán ñöôïc tham chieáu khoâng töôøng minh baèng con troû, laïi laø moät ñoái 
töôïng phaùt sinh ra vieäc goïi haøm toaùn töû. Coù nghiaõ laø, toaùn haïng beân traùi laø moät ñoái 
töôïng cuûa chính lôùp ño

ù.  

 
Ñoái vôùi boä cheøntoaùn haïng beân traùi (cuûa <<) laø moät stream thay vì moät ñoái töôïng, 
vaø toaùn haïng beân phaûi laø moät ñoái töôïng caàn ñöôïc keát xuaát. 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

215 

 
@ C++ cho pheùp boä cheøn laø haøm friend cuûa lôùp maø noù thao taùc. 
 
Ví duï 5.1

 

Lôùp coord chöùa boä cheøn laø haøm friend 

// Use a friend inserter for objects of type coord. 
#include <iostream.h> 
 
class coord { 
  int x, y
public: 
  coord() { x = 0; y = 0; } 
  coord(int i, int j) { x = i; y = j; } 
  friend ostream &operator<<(ostream &stream, coord ob)
}; 
 
ostream &operator<<(ostream &stream, coord ob) 

  stream << ob.x << ", " << ob.y << '\n'; // xaây döïng boä cheøn ôû möùc toång quaùt hoaù 
  return stream

   // 

vôùi 

stream laø moät stream baát ky

ø 


 
int main() 

  coord a(1, 1), b(10, 23); 
 
  cout << a << b; 
  return 0; 

 
 
@ Laäp trình vieân neân traùnh caùch xaây döïng boä cheøn bò haïn cheá bôûi vieäc keát xuaát 
thoâng tin ra thieát bò xuaát chuaån gaén vôùi stream cout. 
 
 
 
ostream &operator<<(ostream &stream, coord ob) 

Keát quaû chöông trình 
1, 1 
10, 23 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

216 

  cout << ob.x << ", " << ob.y << '\n'; 
  return stream;  

 
Ví duï 5.2

 

Lôùp coord chöùa boä cheøn khoâng phaûi laø haøm friend 

// Create an inserter for objects of type coord, using  a non-friend inserter.  
#include <iostream.h> 
 
class coord { 
public: 
  int x, y;  // must be public 
  coord() { x = 0; y = 0; } 
  coord(int i, int j) { x = i; y = j; } 
}; 
 
// An inserter for the coord class. 
ostream &operator<<(ostream &stream, coord ob) 

  stream << ob.x << ", " << ob.y << '\n'; 
  return stream

 
int main() 

  coord a(1, 1), b(10, 23); 
  cout << a << b; 
 
  return 0; 

 
 

• 

Moät boä cheøn khoâng chæ giôûi haïn ôû vieäc xuaát thoâng tin daïng vaên baûn. Noù coù theå 

thöïc hieän caùc thao taùc

 hay chuyeån ñoåi thoâng tin caàn thieát ñeå keát xuaát thoâng tin ra 

thieát bò rieâng bieät

 hay moät tình huoáng rieâng bieät naøo ñoù. 

 
Ví duï 5.3

 

Boä cheøn xuaát thoâng tin ra maùy veõ (plotter) 

 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

217 

// This program draws right triangles 
#include <iostream.h> 
 
class triangle { 
  int height, base; 
public: 
  triangle(int h, int b) { height = h; base = b; } 
  friend ostream &operator<<(ostream &stream, triangle ob); 
}; 
 
// Draw a triangle. 
ostream

 &operator<<(ostream &stream, triangle ob) 


  int i, j, h, k; 
 
  i = j = ob.base - 1; 
 
  for( h = ob.height - 1;  h ; h--) { 
    for( k = i;  k;  k--)  

 stream << ' '; 

    stream << '-'; 
     
    if( j != i) { 
      for( k = j - i - 1;  k;  k--)    stream << ' '; 
      stream << '-'; 
    } 
 
    i--; 
    stream << '\n'; 
  } 
 
  for( k = 0;  k < ob.base;  k++)   stream << '-'; 
  stream << '\n'; 
 
  return stream

 
 

Keát quaû chöông trình laø  
3 hình tam giaùc vuoâng ñoàng daïng vôùi
kích thöôùc khaùc nhau 

 

 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

218 

 
int main() 

  triangle t1(5, 5), t2(10, 10), t3(12, 12); 
 
  cout << t1; 
  cout << endl << t2 << endl << t3; 
 
  return 0; 

 
 
Baøi taäp V 
 
1. Cho lôùp strtype vaø ñoaïn chöông trình sau. Haõy taïo boä cheøn cho lôùp strtype ñeå xuaát 
chuoãi kyù töï ra maøn hình. 
 
#include <iostream.h> 
#include <string.h> 
#include <stdlib.h> 
 
class strtype { 
  char *p; 
  int len; 
public: 
  strtype(char *ptr); 
  ~strtype() {delete [] p;} 
  friend ostream &operator<<(ostream &stream, strtype &ob); 
}; 
 
strtype::strtype(char *ptr) 

  len = strlen(ptr)+1; 
  p = new char [len]; 
  if(!p) { 
    cout << "Allocation error\n"; 
    exit(1); 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

219 

  } 
  strcpy(p, ptr); 

 
// Create operator<< inserter function here. 
// ... 
 
int main() 

  strtype s1("This is a test."), s2("I like C++."); 
 
  cout << s1 << '\n' << s2; 
  return 0; 

 
2. Haõy thay theá haøm show() trong chöông trình sau baèng boä cheøn do baïn taïo ra  
#include <iostream.h> 
 
class planet { 
protected: 
  double distance;   // miles from the sun 
  int revolve;   

// in days 

public: 
  planet(double d, int r) { distance = d; revolve = r; } 
}; 
 
class earth : public planet { 
  double circumference; // circumference of orbit 
public: 
  earth(double d, int r) : planet(d, r) { 
    circumference = 2*distance*3.1416; 
  } 
 
 
 
  // Rewrite this so that it displays the information using  an inserter function. 
  void show() { 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

220 

    cout << "Distance from sun: " << distance << '\n'; 
    cout << "Days in obit: " << revolve << '\n'; 
    cout << "Circumference of orbit: " << circumference << '\n'; 
  } 
}; 
 
int main() 

  earth ob(93000000, 365); 
 
  cout << ob; 
 
  return 0; 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
VI. Taïo boä chieát (extractor) 
 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

221 

• 

Trong C++, thao taùc nhaäp coøn ñöôïc goïi laø chieát (extractor), toaùn töû >> coøn goïi 

laø toaùn töû chieát. Khi quaù taûi toaùn töû naøy, nghiaõ laø taïo moät haøm chieát, hay coøn goïi 
laø boä chieát (extractor) , do toaùn töû >> thöïc hieän chöùc naêng laáy thoâng tin töø moät 
stream. 

 
Cuù phaùp caùc boä chieát 
 

istream

 &operator >> (istream &stream, class_name &ob) 

 { 
 

 

// body of extractor 

 
stream : tham soá thöù nhaát tham chieáu ñeán moät stream nhaäp istream.  
ob 

: tham soá thöù hai tham chieáu ñeán ñoái töôïng nhaän thoâng tin nhaäp vaøo  

 
Boä chieát seõ traû veà moät tham chieáu ñeán stream nhaäp kieåu istream.  
 
Noäi dung cuûa boä chieát

 coù theå thöïc hieän baát kyø thuû tuïc naøo. Tuy nhieân, neân giôùi haïn 

chöùc naêng cuûa noù trong phaïm vi nhaäp thoâng tin. 
 
 

• 

Moät boä chieát khoâng ñöôïc pheùp laø thaønh phaàn cuûa lôùp maø boä chieát naøy thao taùc. 

 

C++ cho pheùp boä cheøn laø haøm friend cuûa lôùp maø noù thao taùc. 

 
Ví duï 6.1 

Taïo boä chieát cho lôùp coord 

// Add a friend extractor for objects of type coord. 
#include <iostream.h> 
 
class coord { 
  int x, y; 
public: 
  coord() { x = 0; y = 0; } 
  coord(int i, int j) { x = i; y = j; } 
  friend ostream &operator<<(ostream &stream, coord ob); 
  friend istream &operator>>(istream &stream, coord &ob)
}; 
ostream &operator<<(ostream &stream, coord ob) 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

222 

  stream << ob.x << ", " << ob.y << '\n'; 
  return stream; 

 
istream

 &operator>>(istream &stream, coord &ob) 


  cout << "Enter coordinates: ";       // thoâng baùo nhaäp döõ lieäu naøy laø caàn thieát ôû boä 
chieát 
  stream >> ob.x >> ob.y; 
  return stream

 
int main() 

  coord a(1, 1), b(10, 23); 
 
  cout << a << b; 
 
  cin >> a; 
  cout << a; 
 
  return 0; 

 
 
Ví duï 6.2 

Lôùp inventory löu thoâng tin kieåm keâ haøng toàn kho goàm teân haøng, löôïng 
toàn vaø trò giaù, chöùa boä cheøn vaø boä chieát. 

#include <iostream.h> 
#include <string.h> 
 
class inventory { 
  char item[40];  

// name of item 

  int onhand;   

// number on hand 

  double cost;   

 

// cost of item 

public: 
  inventory(char *i, int o, double c) 
  { 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

223 

    strcpy(item, i); 
    onhand = o; 
    cost = c; 
  } 
  friend ostream &operator<<(ostream &stream, inventory ob); 
  friend istream &operator>>(istream &stream, inventory &ob)
}; 
 
ostream &operator<<(ostream &stream, inventory ob) 

  stream << ob.item << ": " << ob.onhand; 
  stream << " on hand at $" << ob.cost << '\n'; 
 
  return stream; 

 
istream

 &operator>>(istream &stream, inventory &ob


  cout << "Enter item name: "; 
  stream >> ob.item; 
  cout << "Enter number on hand: "; 
  stream >> ob.onhand; 
  cout << "Enter cost: "; 
  stream >> ob.cost; 
 
  return stream

 
int main() 

  inventory ob("hammer", 4, 12.55); 
 
  cout << ob; 
  cin >> ob; 
 
  cout << ob; 
 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

224 

  return 0; 

 
 
Baøi taäp VI 
 
1. Boå sung vaøo lôùp strtype trong baøi taäp 1 phaàn V, chöông 7, moät boä chieát ñeå nhaäp 
thoâng tin cho lôùp strtype. 
 
2. Haõy taïo ra moät lôùp factor duøng ñeå löu moät giaù trò nguyeân num vaø thöøa soá nhoû nhaát 
cuûa noù laø lfact. Haõy taïo boä cheøn vaø boä chieát cho lôùp treân. 
 
 
Baøi taäp chöông 7 
 
1. Vieát moät chöông trình ñeå trình baøy giaù trò 1000 ôû daïng thaäp phaân, thaäp luïc phaân vaø 
baùt phaân, söû duïng caùc côø ñònh daïng cuûa ios. 
 
2. Vieát moät chöông trình ñeå trình baøy giaù trò 1000.1234 trong moät tröôøng coù chieàu 
daøi 20 coät, con soá ñöôïc canh bieân traùi, soá coù hai chöõ soá sau daáu chaám thaäp phaân, vaø 
ñöôïc laáp ñaày choã troáng baèng kyù töï * , söû duïng caùc côø ñònh daïng cuûa ios. 
 
3. Thöïc hieän laïi baøi taäp 1 vaø 2, söû duïng boä taïo thao taùc nhaäp/xuaát thay cho côø ñònh 
daïng. 
 
4. Haõy taïo boä cheøn vaø boä chieát cho lôùp pwr tính haøm muõ x^n trong chöông trình sau 
 
class pwr { 
  int base; 
  int exponent; 
  double result;  

// base to the exponent power 

public: 
  pwr(int b, int e); 
}; 
 
pwr::pwr(int b, int e) 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

225 

  base = b; 
  exponent = e; 
 
  result = 1; 
  for( ; e; e--)  

result = result * base; 


5. Haõy taïo moät lôùp box ñeå löu tröõ thoâng tin veà kích thöôùc cuûa moät hình vuoâng. Haõy 
taïo boä cheøn vaø boä chieát cho lôùp box ñeå in hình vuoâng ñoù ra maøn hình.  
 
6. Haõy taïo boä cheøn ñeå xuaát noäi dung cuûa moät stack cuûa lôùp stack sau 
 
#include <iostream.h> 
#define SIZE 10 
 
// Declare a stack class for characters 
class stack {  
  char stck[SIZE];   // holds the stack 
  int tos;  

 

// index of top-of-stack 

public: 
  stack();  
  void push(char ch);  

// push character on stack 

  char pop();   

// pop character from stack 

}; 
 
// Initialize the stack 
stack::stack() 

  tos = 0; 

 
// Push a character. 
void stack::push(char ch) 

  if(tos==SIZE) { 
    cout << "Stack is full\n"; 
    return; 
  } 

background image

Chöông 7   Heä thoáng Nhaäp / Xuaát  C++                                       

 

 

226 

  stck[tos] = ch; 
  tos++; 

 
// Pop a character. 
char stack::pop() 

  if(tos==0) { 
    cout << "Stack is empty\n"; 
    return 0;    

// return null on empty stack  

  } 
  tos--; 
  return stck[tos];   

 
7. Haõy vieát chöông trình chöùa lôùp watch coù bieán rieâng t vôùi kieåu döõ lieäu laø time_t. 
Haøm taïo cuûa lôùp naøy duøng haøm thôøi gian chuaån time() ñeå laáy giôø cuûa heä thoáng vaø 
löu laïi vaøo bieán t. Haõy taïo boä cheøn ñeå trình baøy thôøi gian. Söû duïng caùc haøm 
localtime() vaø asctime() . 
 
8. Cho lôùp ft_to_inche duøng ñeå ñoåi ñôn vò chieàu daøi töø feet sang inch. Haõy taïo boä 
chieát cho lôùp naøy ñeå nhaäp giaù trò baèng feet. Haõy taïo boä cheøn duøng ñeå trình baøy soá ño 
ôû ñôn vò laø feet vaø inch. Vieát chöông trình ñeå bieåu dieãn hoaït ñoäng cuûa boä cheøn vaø boä 
chieát. 
 
class ft_to_inches { 
  double feet; 
  double inches; 
public: 
  void set(double f) { 
    feet = f; 
    inches = f * 12; 
    // inserter and  extractor  

 

  } 
}; 

background image

 

 

 
Chöông 8   
 

Nhaäp/Xuaát C++ naâng cao 

 
 
 
 
 
 
 
 
 
 

• 

Taïo Boä thao taùc Nhaäp/Xuaát  

 

• 

Nhaäp/Xuaát File 

 

• 

Nhaäp/Xuaát File nhò phaân khoâng ñònh daïng 

 

• 

Caùc haøm Nhaäp/Xuaát nhò phaân 

 

• 

Truy caäp ngaãu nhieân 

 

• 

Kieåm tra traïng thaùi Nhaäp/Xuaát 

 

• 

Nhaäp/Xuaát theo ñôn ñaët haøng vaø caùc File 

 

• 

Nhaäp/Xuaát theo maûng 

 
 
 

 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

228 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

229 

I/ Taïo Boä thao taùc Nhaäp/Xuaát  

 
Ngoaøi boä cheøn vaø boä chieát, coù theå söûa ñoåi heä thoáng nhaäp/xuaát cuûa C++ baèng caùch 
taïo ra boä thao taùc nhaäp/xuaát töï taïo

. Noù coù hai lyù do : 

*  moät boä thao taùc coù theå hôïp nhaát moät daõy caùc thao taùc nhaäp/xuaát thaønh moät boä thao    
taùc töï taïo. 
*  moät boä thao taùc nhaäp/xuaát töï taïo caàn thieát khi nhaäp/xuaát treân caùc thieát bò khoâng 
chuaån (maùy in ñaëc bieät hay heä thoáng nhaän daïng quang hoïc) . 

 

Coù hai loaïi boä thao taùc, moät duøng cho caùc stream nhaäp, moät duøng cho caùc stream 
xuaát. Ngoaøi ra ngöôøi ta coøn phaân thaønh hai nhoùm : boä thao taùc coù tham soá vaø boä thao 
taùc khoâng coù tham soá

, chuùng khaùc nhau veà caùch taïo ra boä thao taùc. Vieäc taïo ra boä 

thao taùc coù tham soá khoâng thuoäc phaïm vi baøi giaûng naøy. 
 

• 

Daïng toång quaùt cuûa caùc boä thao taùc xuaát khoâng coù tham soá : 

 

ostream  &manip_name(ostream &stream) 
{  

 

 

// program codes 

 return 

stream 

 
manip_name

   

teân cuûa boä thao taùc ñöôïc taïo ra 

 
Löu yù : boä thao taùc treân coù ñoái soá laø moät tham chieáu ñeán stream maø noù thao taùc, khi 
goïi boä naøy, khoâng ñöôïc keøm theo teân boä thao taùc baát kyø moät ñoái soá naøo. 
 
 

• 

Daïng toång quaùt cuûa caùc boä thao taùc nhaäp  khoâng coù tham soá : 

 

istream  &manip_name(istream &stream) 
{  

 

 

// program codes 

 return 

stream 

 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

230 

Moät boä thao taùc nhaäp nhaän moät tham chieáu ñeán stream maø noù thao taùc. Stream naøy 
phaûi ñöôïc traû veà bôûi boä thao taùc. 
 
Ví duï 1.1 

Chöông trình taïo ra boä thao taùc xuaát setup(). Khi ñöôïc goïi, boä naøy seõ 

thieát laäp ñoä roäng tröôøng laø 10, ñoä chính xaùc laø 4 vaø daáu "* " laø kyù töï laáp ñaày. 
#include <iostream.h> 
 
ostream &setup(ostream &stream) 

  stream.width(10); 
  stream.precision(4); 
  stream.fill('*'); 
 
  return stream

 
int main() 

  cout << setup << 123.123456; 
  return 0; 

 
Keát quûa chöông trình 
**123.1234 
 
 
Ví duï 1.2 

Hai boä thao taùc atn() vaø note() ñôn giaûn sau ñaây laøm goïn hôn ñoaïn 

chöông trình in caùc töø hay ñoaïn caâu hay laëp laïi trong chöông trình. 
 
#include <iostream.h> 
// Attention: 
ostream &atn(ostream &stream) 

  stream << "Attention: "; 
  return stream; 

 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

231 

// Please note: 
ostream &note(ostream &stream) 

  stream << "Please Note: "; 
  return stream; 

 
int main() 

  cout << atn << "High voltage circuit\n"; 
  cout << note << "Turn off all lights\n"; 
 
  return 0; 

 
 
Ví duï 1.3 

Chöông trình taïo boä thao taùc nhaäp getpass() thöïc hieän baùo tieáng chuoâng 

vaø thoâng baùo ñeà nghò nhaäp maät khaåu. 
 
#include <iostream.h> 
#include <string.h> 
 
// A simple input manipulator 
istream &getpass(istream &stream) 

  cout << '\a';  // sound bell 
  cout << "Enter password: "; 
 
  return stream

 
int main() 

  char pw[80]; 
 
  do { 
    cin >> getpass >> pw; 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

232 

  } while (strcmp(pw, "password")); 
 
  cout << "Logon complete\n"; 
 
  return 0; 

 
 
Baøi taäp I 
 
1. Haõy taïo moät boä thao taùc môùi teân laø td() duøng ñeå hieän giôø vaø ngaøy hieän taïi cuûa heä 
thoáng. 
 
2. Haõy taïo moät boä thao taùc môùi teân laøsethex() duøng ñeå thieát laäp caùc traïng thaùi ñeå in 
moät soá thaäp luïc phaân, ñaët caùc côø uppercase vaø showbase. Ngoaøi ra, haõy taïo moät boä 
thao taùc xuaát teân laø reset() ñeå phuïc hoài laïi traïng thaùi tröôùc khi goïi sethex(). 
 
3. Haõy taïo moät boä thao taùc môùi teân laø skipchar() duøng ñeå ñoïc vaø boû qua möôøi kyù töï 
lieân tieáp töø moät stream nhaäp. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

233 

II/ Nhaäp/Xuaát File 

 
1/ Khaùi nieäm 
Ñeå söû duïng nhaäp/xuaát file trong chöông trình caàn phaûi naïp file fstream.h . File naøy 
ñònh nghiaõ nhieàu lôùp goàm ifstreamofstream vaø fstream. Ba lôùp naøy ñöôïc suy daãn 
töø hai lôùp istream vaø ostream, vaø ios laø lôùp cô sôû cuûa chuùng. Do ñoù caùc lôùp ifstream, 
ofstream vaø fstream cuõng coù theå truy xuaát ñeán taát caû caùc thao taùc ñaõ ñònh nghóa trong 
ios

 
Trong C++, moät file ñöôïc môû baèng caùch lieân keát noù vôùi moät stream. Coù ba loaïi stream 
: nhaäp, xuaát vaø nhaäp/xuaát

. Tröôùc khi môû file phaûi taïo ra stream töông öùng.  

 
Ñeå taïo moät stream nhaäp, caàn khai baùo stream ñoù thuoäc lôùp ifstream.  
Ñeå taïo moät stream xuaát, caàn khai baùo stream ñoù thuoäc lôùp ofstream.  
Ñoái vôùi stream thöïc hieän caû thao taùc nhaäp vaø xuaát, caàn khai baùo stream ñoù thuoäc lôùp 
fstream

 
Ví duï 

ifstream  

in

;    // input stream 

ofstream  

out

;   // output stream 

fstream  

io

;     // input and output stream 

 
2/ Môû file 
a/ Sau khi taïo ra moät stream, coù theå môû file gaén vôùi stream ñoù baèng haøm open()
Haøm naøy laø haøm thaønh phaàn cuûa ba stream noùi treân, daïng toång quaùt : 
 void 

open

(const char *filename, int  mode, int  access); 

filename 

teân cuûa file caàn môû, coù theå ñi keøm vôùi ñöôøng daãn.  

mode

   

xaùc ñònh cheá ñoä cuûa file ñöôïc môû. 

access  

xaùc ñònh caùch truy caäp file 

 
 
@ Caùc giaù trò nguyeân cuûa mode, coù theå laø moät hay nhieàu giaù trò (ñöôïc keá thöøa bôûi 
fstream.h) 

• 

Cheá ñoä ios::app laøm cho keát xuaát ñöôïc theâm vaøo cuoái cuûa file. Duøng cho caùc 

file xuaát. 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

234 

• 

Cheá ñoä ios::ate cho pheùp chuyeån ñeán vò trí cuoái file ngay sau khi file ñöôïc môû. 

Löu yù, maëc duø ñang ôû vò trí cuoái file, caùc thao taùc nhaäp/xuaát vaãn coù theå xuaát 
hieän ôû baát cöù vò trí naøo cuûa file. 

• 

Cheá ñoä ios::in xaùc ñònh file ñöôïc môû laø file nhaäp. Cheá ñoä ios::out xaùc ñònh file 

ñöôïc môû laø file xuaát

 
Tuy nhieân, vieäc taïo ra moät stream baèng caùc khai baùo noù thuoäc lôùp ifstream ngaàm 
ñònh noù laø moät stream nhaäp, cuõng nhö khai baùo stream thuoäc lôùp ofstream ngaàm 
ñònh noù laø moät stream xuaát. Trong hai tröôøng hôïp treân, khoâng caàn phaûi xaùc ñònh caùc 
giaù trò ios::in vaø ios::out khi môû file. 
 

• 

Cheá ñoä ios::binary laøm cho file ñöôïc môû ôû cheá ñoä nhò phaân.  

 
Theo maëc ñònh, taát caû caùc file ñöôïc môû ôû cheá ñoä vaên baûn (text mode). Trong cheá ñoä 
vaên baûn, seõ coù moät soá tröôøng hôïp kyù töï seõ bò chuyeån ñoåi. Ví duï, kyù töï taïo doøng môùi ( 
'\n' ) seõ ñöôïc chuyeån thaønh chuoåi lieân tieáp nhau cuûa hai kyù töï xuoáng doøng (carriage 
return, maõ 13), vaø theâm moät doøng (line-feed, maõ 10). 
 
Khi hoaït ñoäng ôû cheá ñoä nhò phaân, seõ khoâng coù baát kyø moät tröôøng hôïp chuyeån ñoåi kyù töï 
naøo

. Baát kyø moät file naøo ñeàu coù theå hoaït ñoäng ôû hai cheá ñoä vaên baûn hay nhò phaân.  

 

• 

Cheá ñoä ios::nocreate laøm cho vieäc goïi haøm open() bò thaát baïi neáu file ñöôïc môû 

laø moät file môùi (chöa coù saün treân ñiaõ). Coøn ios::noreplace laøm cho vieäc goïi haøm 
open()

 bò thaát baïi neáu file ñöôïc môû ñaõ coù saün treân ñiaõ. 

 

• 

Cheá ñoä ios::trunc laøm cho khi file coù saün truøng teân vôùi file ñöôïc môû seõ bò xoaù 

saïch noäi dung. 

 
Coù theå söû duïng keát hôïp hai hay nhieàu cheá ñoä ôû treân baèng pheùp toaùn OR. 
 
@ Caùc giaù trò cuûa ñoái soá access xaùc ñònh caùch truy caäp file. 
Giaù trò ngaàm ñònh cuûa ñoái soá naøy laø  filebuf::openprot (filebuf laø lôùp cha cuûa caùc 
lôùp stream). Trong moâi tröôøng UNIX noù coù giaù trò 0x644 ñoái vôùi caùc file thoâng 
thöôøng. 
 
Trong moâi tröôøng DOS/WINDOWS giaù trò cuûa ñoái soá access qui ñònh maõ thuoäc tính 
cuûa file, bao goàm : 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

235 

 
 

Thuoäc tính   

YÙ nghiaõ 

 

 

Archive 

File bình thöôøng : ghi / ñoïc (maëc ñònh) 

 

 

Read only  File chæ ñoïc 

  2 Hidden File 

aån 

  4 System File 

heä 

thoáng 

  8 Save 

 Thuoäc 

tính 

löu 

tröõ 

 
 
Coù theå söû duïng keát hôïp hai hay nhieàu thuoäc tính ôû treân baèng pheùp toaùn OR. 
 
 

• 

Ví duï ñoaïn chöông trình sau minh hoaï vieäc môû file bình thöôøng trong 

DOS/WINDOWS 

 ofstream 

 

out 

// khai baùo stream xuaát 

 

 

out.open

("test.txt", ios::out, 0) ; 

 

hoaëc 

out.open

("test.txt") ; // lôøi goïi ngaén goïn, thoâng thöôøng. 

 
 

• 

Ñeå môû file nhaäp/xuaát, caàn phaûi xaùc ñònh caû hai cheá ñoä ios::in vaø ios::out cho ñoái 

soá  mode, ñöôïc minh hoaï sau ñaây. Löu yù, khoâng coù giaù trò maëc ñònh cho tröôøng 
hôïp naøy. 

 fstream 

 

mystream

// khai baùo stream xuaát 

 

 

mystream.open

("test.txt", ios::in | ios::out) ; 

 
Neáu haøm open() khoâng thöïc thi ñöôïc, stream ñöôïc traû veà seõ mang giaù trò khoâng. Do 
ñoù, caàn kieåm tra laïi vieäc môû file coù thaønh coâng hay khoâng, tröôùc khi truy xuaát noù. Ví 
duï : 
  if(! 

mystream) 

 

 

 

cout << "Can't open file \n"; 

   // 

handle 

error 

 
 
b/ Duøng haøm taïo ñeå môû file 
 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

236 

Thoâng thöôøng, khoâng caàn duøng haøm open() ñeå môû file, vì caùc lôùp ifstream
ofstream

 vaø fstream ñaõ coù saün caùc haøm taïo duøng ñeå môû file moät caùch töï ñoäng. Caùc 

haøm taïo naøy coù caùc ñoái soá gioáng heät nhö cuûa haøm open(). Daïng thoâng thöôøng môû file 
ñeå nhaäp

 : 

 
 

ifstream

 mystream("test.txt"); 

 
Caàn kieåm tra laïi vieäc môû file coù thaønh coâng hay khoâng, tröôùc khi truy xuaát noù. 
 
3/ Ñoùng file 
Duøng haøm void close(). Haøm naøy khoâng coù ñoái soá vaø khoâng traû veà giaù trò naøo caû. 
Ví duï ñoùng moät file ñang gaén vôùi stream mystream, caàn goïi : 

 

 

mystream.close()

 

• 

Ñeå kieåm tra tình traïng heát file duøng haøm eof() 

int  eof()

 

Haøm traû veà   giaù trò 

 0   khi ñang ôû tình traïng cuoái file. 

 

 

 

giaù trò = 0   ngöôïc laïi. 

 

Ví duï   

mystream.eof()

 
 
4/ Truy xuaát noäi dung treân file 
Toaùn töû xuaát <<  vaø toaùn töû nhaäp >> ñöôïc söû duïng ñeå truy xuaát noäi dung treân file, 
caàn phaûi thay caùc stream cin vaø cout baèng stream lieân keát vôùi file. 
 
Thoâng tin löu treân file coù cuøng ñònh daïng nhö khi noù ñöôïc trình baøy treân maøn hình. 
Do ñoù, caùc file taïo ra baèng toaùn töû xuaát <<  vaø caùc file ñöôïc ñoïc vaøo baèng toaùn töû 
nhaäp >> ñeàu laø caùc file vaên baûn coù ñònh daïng
 
 
Ví duï 2.1 

Taïo moät file xuaát, ghi leân file, ñoùng file. Môû file ñoù nhö moät file nhaäp, 

ñoïc noäi dung cuûa file. 
 
#include <iostream.h> 
#include <fstream.h> 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

237 

#include <iomanip.h> 
 
int main() 

  ofstream fout("test.txt");  // create output file 
 
  if(!fout) { 
    cout << "Cannot open output file.\n"; 
    return 1; 
  } 
 
  fout << "Hello!\n"; 
  fout << 100 << ' ' << hex << 100 << endl; 
 
  fout.close()
 
  ifstream  fin("test.txt");  // open input file 
 
  if(!fin) { 
    cout << "Cannot open input file.\n"; 
    return 1; 
  } 
 
  char str[80]; 
  int i, j; 
 
  fin >> str >> i >> j; 
  cout << str << ' ' << i << ' ' << j << endl; 
 
  fin.close()
 
  return 0; 

 
 
Keát quaû chöông trình, noäi dung trong file test.txt 
 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

238 

Hello! 
100 64 
 
 
Ví duï 2.2 

Chöông trình ñoïc töø baøn phím moät chuoåi kyù töï, ghi leân file, ñoùng file. 

Chöông trình keát thuùc khi nhaäp moät doøng troáng. Môû file ñoù nhö moät file nhaäp, ñoïc 
noäi dung cuûa file. 
 
// WRITE.CPP 
#include <iostream.h> 
#include <fstream.h> 
#include <iomanip.h> 
 
int  main(int argc, char *argv[]) //  argc     : soá caùc tham soá ,  

// *argv[] : chöùa noäi dung caùc tham soá 


  if(argc!=2) { 
    cout << "Usage: WRITE  <filename> \n"; 

// argv[0] = '\<path>\WRITE.EXE' 
// argv[1] = '<filename>' 

    return 1; 
  } 
 
  ofstream out(argv[1]); // output file 
 
  if(!out) { 
    cout << "Cannot open output file.\n"; 
    return 1; 
  } 
 
  char str[80]; 
  cout << "Write strings to disk, '$' to stop\n"; 
 
  do { 
    cout << ": "; 
    cin >> str; 
    out << str << endl; 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

239 

  } while (*str != '$'); 
 
  out.close()
  return 0; 

 
Ví duï 2.3 

Chöông trình seõ sao cheùp moät text file, trong ñoù caùc daáu khoaûng caùch 

seõ ñöôïc thay baèng daáu '|'. 
 
// CONVERT.CPP 
// Convert spaces to |s. 
#include <iostream.h> 
#include <fstream.h> 
 
int  main(int argc, char *argv[]

  if(argc != 3) { 
    cout << "Usage:  CONVERT  <input>  <output>\n"; 
    return 1; 
  } 
 
  ifstream  fin(argv[1]);   // open input file to read 
  ofstream fout(argv[2]);   // create output file to write 
 
  if(!fout) { 
    cout << "Cannot open output file.\n"; 
    return 1; 
  } 
 
  if(!fin) { 
    cout << "Cannot open input file.\n"; 
    return 1; 
  } 
 
  char ch; 
 
  fin.unsetf(ios::skipws);    

// do not skip spaces 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

240 

  while(!fin.eof()) { 
    fin >> ch
    if(ch == ' ' )  

 

ch = '|'; 

    if(!fin.eof()) 

 

fout << ch

  } 
 
  fin.close(); 
  fout.close(); 
  return 0; 

 
 
Baøi taäp II 
 
1. Vieát chöông trình sao cheùp moät text file sang moät file môùi, ñeám vaø in ra soá kyù töï 
ñaõ cheùp. Taïi sao soá löôïng  caùc kyù töï naøy khaùc vôùi soá löôïng  caùc kyù töï khi in file keát 
quaû ra maøn hình. 
 
2. Vieát chöông trình ñeå ghi baûng döõ lieäu sau ñaây vaøo moät file coù teân laø phone.txt 
 
Nguyeãn Coâng Tröù   08.8980168 
Phaïm Nguõ Laõo 

04.2325678 

Traàn Nguyeân Haõn  04.6781234 
 
3. Vieát chöông trình ñeám soá löôïng töø coù trong moät text file baát kyø. 
 
 
 
 
 
 
 
 
 
 

III/ Nhaäp/Xuaát File nhò phaân khoâng ñònh daïng 

Vieäc nhaäp/xuaát file nhò phaân khoâng ñònh daïng linh ñoäng hôn nhaäp/xuaát text file. 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

241 

 
1/ Caùc haøm nhaäp/xuaát caáp thaáp 

• 

Ñoïc ghi töøng kyù töï 

Daïng phoå bieán cuûa chuùng : 

 
 

istream &get

(char  &ch); 

ostream &put

(char  ch); 

 
Haøm get() ñoïc moät kyù töï töø stream töông öùng vaø gaùn kyù töï ñoù vaøo noäi dung cuûa ch. 
Haøm traû veà moät tham chieáu ñeán stream, noù seõ laø NULL neáu ñeán cuoái file. 
 
Haøm put() ghi (xuaát) noäi dung cuûa ch  ra moät stream vaø traû veà moät stream. 
 

• 

Ñoïc ghi caùc khoái döõ lieäu nhò phaân 

 

istream &read

(unsigned char  *buf, int num); 

ostream &write

(const unsigned char  *buf, int num); 

 
Haøm read() ñoïc moät soá löôïng num caùc byte töø stream töông öùng vaø ghi leân moät vuøng 
ñeäm ñöôïc troû bôûi buf
 
Haøm write() ghi moät soá löôïng num caùc byte ôû vuøng ñeäm ñöôïc troû bôûi buf ñeán stream 
töông öùng. 
 
Neáu file ñöôïc ñoïc heát tröôùc khi ñuû num kyù töï, haøm read() hoaøn taát bình thöôøng vaø 
vuøng ñeäm chöùa heát soá kyù töï cuûa laàn ñoïc cuoái. Ñeå bieát laàn cuoái naøy coù bao nhieâu kyù 
töï ñöôïc ñöa ra vuøng ñeäm, duøng haøm gcount() coù daïng 
 

int  gcount(); 

 
Haøm seõ traû veà giaù trò laø toång soá kyù töï ñoïc ñöôïc ôû laàn ñoïc cuoái ngay tröôùc khi heát file. 
 
Löu yù

 : vieäc thieát laäp cheá ñoä ios::binary chæ nhaèm muïc ñích ngaên ngöøa vieäc chuyeån 

ñoåi kyù töï. Khi söû duïng caùc haøm nhaäp/xuaát file nhò phaân khoâng ñònh daïng, khoâng caàn 
môû file ôû cheá ñoä ios::binary. 
 
Ví duï 3.1

 

Chöông trình xuaát noäi dung cuûa moät file baát kyø ra maøn hình 

 
// PR.CPP 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

242 

#include <iostream.h> 
#include <fstream.h> 
 
int main(int argc, char *argv[]

  char ch; 
 
  if(argc!=2) { 
    cout << "Usage: PR <filename>\n"; 
    return 1; 
  } 
 
  ifstream  in(argv[1]ios::in | ios::binary); 
 
  if(!in) { 
    cout << "Cannot open file.\n"; 
    return 1; 
  } 
  while(!in.eof()) { 
    in.get(ch)
    cout << ch; 
  } 
 
  in.close(); 
  return 0; 

 
 
Ví duï 3.2

 

Chöông trình ghi caùc kyù töï leân moät file cho ñeán khi ngöôøi duøng nhaäp 
vaøo kyù töï '$' . 

 
// WRITE.CPP 
#include <iostream.h> 
#include <fstream.h> 
int  main(int argc, char *argv[]

  char ch; 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

243 

 
  if(argc!=2) { 
    cout << "Usage: WRITE <filename>\n"; 
    return 1; 
  } 
 
  ofstream  out

(argv[1]ios::out | ios::binary); 

 
  if(!out) { 
    cout << "Cannot open file.\n"; 
    return 1; 
  } 
 
  cout << "Enter a $ to stop\n"; 
  do { 
    cout << ": "; 
    cin.get(ch); 
    out.put(ch)
  } while (ch != '$'); 
  out.close(); 
  return 0; 

 
Löu yù

 : chöông trình duøng haøm get() ñeå ñoïc kyù töï töø stream cin vaøo. Neáu duøng toaùn 

töû <<  caùc kyù töï khoaûng caùch seõ bò boû qua, trong khi söû duïng haøm get() caùc kyù töï 
khoaûng caùch vaãn ñöôïc nhaän vaøo

 
 
Ví duï 3.3

 

Chöông trình duøng haøm write() ñeå ghi moät soá thöïc kieåu double vaø moät 
chuoãi kyù töï leân moät file coù teân laø test.txt. 

 
#include <iostream.h> 
#include <fstream.h> 
#include <string.h> 
int main() 

  ofstream out("test.txt", ios::out | ios::binary); 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

244 

 
  if(!out) { 
    cout << "Cannot open output file.\n"; 
    return 1; 
  } 
 
  double num = 100.45; 
  char str[] = "This is a test"; 
 
  out.write((char *) &num, sizeof(double)); 
  out.write(str, strlen(str)); 
 
  out.close(); 
 
  return 0; 

 
Löu yù 

: vieäc khai baùo linh hoaït (char *) khi goïi haøm write() laø caàn thieát khi vuøng 

ñeäm khoâng ñöôïc ñònh nghiaõ laø moät daõy kyù töï. Do C++ kieåm tra kieåu raát kyõ, neân moät 
con troû chæ ñeán kieåu döõ lieäu naøy khoâng theå ñöôïc töï ñoäng ñoåi thaønh moät con troû cuûa 
kieåu khaùc. 
 
Ví duï 3.4

 

Chöông trình duøng haøm read() ñeå ñoïc noäi dung text file test.txt töø ví duï 
3 ôû treân. 

 
#include <iostream.h> 
#include <fstream.h> 
 
int main() 

  ifstream  in("test.txt", ios::in | ios::binary); 
 
  if(!in) { 
    cout << "Cannot open input file.\n"; 
    return 1; 
  } 
 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

245 

  double num; 
  char str[80]; 
 
  in.read((char *) &num, sizeof(double)); 
  in.read(str, 14); 
  str[14] = '\0';  

 

// null terminate str 

 
  cout << num << ' ' << str; 
 
  in.close()
  return 0; 

 
 
Ví duï 3.5

 

Chöông trình ghi moät maûng caùc giaù trò kieåu double moät file vaø sau ñoù 
ñoïc laïi noäi dung file. Chöông trình coøn thoâng baùo soá löôïng caùc kyù töï ñaõ 
ñoïc. 

 
// Demonstrate gcount(). 
#include <iostream.h> 
#include <fstream.h> 
 
int main() 

  ofstream out("test.txt", ios::out | ios::binary); 
  if(!out) { 
    cout << "Cannot open output file.\n"; 
    return 1; 
  } 
 
  double nums[4] = {1.1, 2.2, 3.3, 4.4 }; 
 
  out.write((char *) nums, sizeof(nums)); 
  out.close()
  ifstream in("test.txt", ios::in | ios::binary); 
  if(!in) { 
    cout << "Cannot open input file.\n"; 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

246 

    return 1; 
  } 
 
  in.read((char *) &nums, sizeof(nums)); 
 
  int  i; 
  for(i=0; i<4; i++)  
    cout << nums[i] << ' '; 
 
  cout << '\n'; 
 
  cout << in.gcount() << " characters read\n"; 
  in.close(); 
 
  return 0; 

 
 
Baøi taäp III 
 
1. Vieát laïi chöông trình trong caùc baøi taäp 1 vaø 3 phaàn II chöông 8, thay baèng caùc haøm 
get(), put(), read() hoaëc write() sao cho phuø hôïp nhaát. 
 
2. Cho lôùp sau ñaây, vieát chöông trình ghi noäi dung cuûa lôùp leân moät file, söû duïng boä 
cheøn.  
 
class  account { 
  int  custnum; 
  char  name[80]; 
  double  balance; 
 
public: 
  account(int c, char *n, double b)  
  { 
    custnum = c; 
    strcpy(name, n); 
    balance = b; 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

247 

  } 
 
  // create inserter here 
   ... 
}; 
 
 

IV/ Caùc haøm Nhaäp/Xuaát nhò phaân 

Hai daïng quaù taûi haøm get() thöôøng duøng : 

• 

istream  &get

(char *buf, int num, char delim = '\n') ; 

 
Haøm get() ñoïc caùc kyù töï vaøo moät daõy ñöôïc chæ bôûi buf, vôùi soá löôïng laø num kyù töï 
hoaëïc khi ñoïc vaøo moät kyù töï phaân caùch delim
 
Neáu trong ñoái soá cuûa haøm khoâng coù ñoái soá delim, giaù trò maëc ñònh cuûa kyù töï phaân 
caùch laø kyù töï sang doøng môùi '\n'. Neáu kyù töï phaân caùch xuaát hieän trong stream nhaäp, 
kyù töï seõ khoâng bò laáy ra, thay vaøo ñoù, kyù töï naøy seõ ôû trong stream cho ñeán khi gaëp 
thao taùc nhaäp khaùc.  
 

• 

int  get

() ;  

Haøm get() traû veà kyù töï keá tieáp trong stream. Neáu gaëp tình traïng heát file, haøm traû veà 
giaù trò EOF (gioáng nhö haøm getc() trong ngoân ngöõ  C). 
 

• 

istream  &getline

(char *buf, int num, char delim = '\n') ; 

Haøm getline() cuõng thöïc hieän nhaäp döõ lieäu, ñoïc vaø boû caùc kyù töï phaân caùch ra khoûi 
stream

 (nhaäp ñöôïc moät chuoãi). Caùc ñoái soá töông töï nhö haøm get() ôû treân. 

 
 

• 

int  peek

() ;  

Haøm peek() coù theå laáy kyù töï tieáp theo trong stream nhaäp maø khoâng caàn phaûi ñöa noù 
ra khoûi stream. Haøm traû veà giaù trò laø kyù töï tieáp theo cuûa stream, neáu heát file, haøm traû 
veà giaù trò EOF. 
 

• 

istream  &putback

(char  ch) ;  

Haøm putback() traû laïi giaù trò vöøa ñoïc vaøo stream. Ñoái soá ch laø kyù töï vöøa ñöôïc ñoïc 
vaøo töø stream. 
 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

248 

 

• 

ostream  &flush

() ;  

Moãi khi thao taùc xuaát ñöôïc thöïc hieän, döõ lieäu khoâng ñöôïc ñöa ra ngay thieát bò vaät lyù 
lieân keát vôùi stream, maø thoâng tin ñoù ñöôïc ñöa vaøo vuøng ñeäm. Khi vuøng ñeäm bò ñaày, 
döõ lieäu cuûa vuøng ñeäm môùi ñöôïc xuaát ra ñiaõ. Tuy nhieân, neáu muoán thoâng tin xuaát ra 
ñiaõ tröôùc khi ñaày vuøng ñeäm

, coù theå duøng haøm flush().  

 
Neân duøng haøm naøy khi maùy tính hoaït ñoäng vôùi nguoàn ñieän hoaït ñoäng khoâng oån ñònh. 
 
Ví duï 4.1 

Duøng haøm getline() nhaäp vaøo moät chuoãi baát kyø. 

 
// Use getline() to read a string that contains spaces. 
#include <iostream.h> 
#include <fstream.h> 
 
int main() 
{  
  char str[80]; 
 
  cout << "Enter your name: "; 
  cin.getline(str, 79)

 

 

// töông töï nhö haøm gets(str) ; 

 
  cout << str << '\n'; 
 
  return 0; 

 
 
Ví duï 4.2 

Duøng haøm peek() vaø putback() trôï giuùp xöû lyù deã daøng khi khoâng bieát 

öôïc kieåu cuûa thoâng tin nhaäp vaøo

// Demonstrate peek(). 
#include <iostream.h> 
#include <fstream.h
#include <ctype.h> 
 
int main() 
{  

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

249 

  char ch; 
  ofstream out("test.txt", ios::out | ios::binary); 
 
  if(!out) { 
    cout << "Cannot open output file.\n"; 
    return 1; 
  } 
 
  char str[80], *p; 
  
  out << 123 << "this is a test" << 23; 
  out << "Hello there!" << 99 << "sdf" << endl; 
  out.close(); 
   
  ifstream in("test.txt", ios::in | ios::binary); 
 
  if(!in) { 
    cout << "Cannot open input file.\n"; 
    return 1; 
  } 
 
  do { 
    p = str; 
    ch = in.peek();    

 

 

// see what type of char is next 

    if(isdigit(ch)) { 
      while(isdigit(*p = in.get() ) )  p++;   // read integer 
      in.putback(*p);   

 

 

// return char to stream 

      *p = '\0';   

 

 

 

// null terminate the string 

      cout << "Integer: " << atoi(str); 
    } 
    else if(isalpha(ch)) {    

 

// read a string 

      while(isalpha(*p = in.get() ) )  

p++; 

      in.putback(*p);  

 

 

 

// return char to stream 

      *p = '\0';   

 

 

 

// null terminate the string 

      cout << "String: " << str; 
    } 
    else in.get();  

 

 

 

// ignore 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

250 

    cout << '\n'; 
  } while(!in.eof()); 
   
  in.close(); 
  return 0; 

 
 
Baøi taäp IV 
 
1. Vieát laïi chöông trình ví duï 4.1 söû duïng haøm get() thay cho haøm getline(). Hoaït 
ñoäng cuûa chöông trình naøy nhö theá naøo ? 
 
2. Vieát chöông trình ñoïc töøng doøng cuûa moät text file vaø in doøng vöøa nhaäp ra maøn 
hình. Söû duïng haøm getline(). 
 
3. Vieát chöông trình minh hoaï hoaït ñoäng cuûa haøm flush() ? 
 
 

V/ Truy caäp ngaãu nhieân 

• 

C++ cung caáp vieäc truy caäp ngaãu nhieân moät file qua caùc haøm : 

 

istream &seekg

(streamoff offset, seek_dir origin) ; 

ostream &seekp

(streamoff offset, seek_dir origin) ; 

 
streamoff

    laø kieåu ñònh nghiaõ trong iostream.h, noù coù theå löu tröõ ñöôïc giaù trò hôïp 

leä  

lôùn nhaát maø offset coù theå nhaän ñöôïc. 

 
seek_dir

  

laø moät kieåu haèng lieät keâ vôùi caùc giaù trò nhö sau : 

 

 

Giaù trò  

YÙ  nghiaõ 

 

 

ios::beg 

tìm töø vò trí ñaàu file 

 

 

ios::cur 

tìm töø vò trí hieän haønh 

 

 

ios::end 

tìm töø vò trí cuoái file 

 
Haøm seekg() dôøi con troû get cuûa file töông öùng moät ñoaïn baèng offset byte töø moät vò 
trí ñöôïc xaùc ñònh baèng origin. 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

251 

 
Haøm seekp() dôøi con troû put cuûa file töông öùng ñi moät ñoaïn baèng offset byte tính töø 
vò trí ñöôïc xaùc ñònh bôûi origin. 
 

• 

Heä thoáng nhaäp/xuaát cuûa C++ söû duïng hai con troû ñeå quaûn lyù moät file.  

 

Thöù nhaát laø con troû get ñeå troû ñeán vò trí seõ ñöôïc ñöa vaøo neáu file ñöôïc thöïc hieän moät 
taùc vuï nhaäp

 nöõa.  

Thöù hai  laø con troû put xaùc ñònh vò trí cuûa file maø moät taùc vuï xuaát tieáp theo seõ ñoïc ra 
töø ñoù. 
 

 

Moãi khi thöïc hieän thao taùc nhaäp/xuaát file con troû seõ ñöôïc töï ñoäng taêng leân ñeå chæ vaøo 
vò trí keá tieáp. Tuy nhieân, vaãn coù theå duøng haøm seekg() vaø seekp() ñeå truy caäp file 
moät caùch ngaãu nhieân. 
 

• 

Coù theå xaùc ñònh vi trí hieän haønh cuûa caùc con troû get vaø put baèng caùc haøm : 

streampos  tellg()

 ; 

streampos  tellp()

 ; 

 
streampos

    laø kieåu ñònh nghiaõ trong iostream.h, noù coù theå löu tröõ ñöôïc giaù trò  

lôùn nhaát maø haøm coù theå traû veà ñöôïc. 

 
Ví duï 5.1 

Duøng haøm seekp() cho pheùp ñoåi moät kyù töï xaùc ñònh cuûa file. Tham soá 

cuûa chöông trình goàm teân file,  soá thöù töï cuûa byte caàn thay theá vaø kyù töï caàn thay. 
 
// CHANGE.CPP 
#include <iostream.h> 
#include <fstream.h> 
#include <stdlib.h> 
 
int main(int argc, char *argv[]

  if(argc != 4) { 
    cout << "Usage: CHANGE  <filename>  <byte>  <char>\n"; 
    return 1; 
  } 
 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

252 

  fstream  out(argv[1], ios::in | ios::out | ios::binary); 
 
  if(!out) { 
    cout << "Cannot open file.\n"; 
    return 1; 
  } 
 
  out.seekp(atoi(argv[2]), ios::beg); 
 
  out.put(*argv[3]); 
  out.close(); 
 
  return 0; 

 
AÙp duïng : 

Cho file test.txt chöùa noäi dung "123 this is a sample" 

 
Keát quûa chöông trình seõ ra sao khi thöïc hieän leänh töø daáu nhaéc MS-DOS : 

 

C:\> CHANGE  test.txt  4  T 

 

 

 
Ví duï 5.2 

Duøng haøm seekg() ñeå ñaët con troû get vaøo vò trí giöõa file vaø trình baøy 

phaàn noäi dung cuûa file töø vò trí naøy cho ñeán cuoái file.  
 
// LOCATE.CPP 
// Demonstrate seekg(). 
#include <iostream.h> 
#include <fstream.h> 
#include <stdlib.h> 
 
int main( int argc, char *argv[]

  char ch; 
 
  if(argc != 3) { 
    cout << "Usage: LOCATE  <filename>  <loc>\n"; 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

253 

    return 1; 
  } 
  ifstream in(argv[1], ios::in | ios::binary); 
  if(!in) { 
    cout << "Cannot open input file.\n"; 
    return 1; 
  } 
 
  in.seekg(atoi(argv[2]), ios::beg); 
 
  while(!in.eof()) {  
    in.get(ch); 
    cout << ch; 
  } 
 
  in.close(); 
  return 0; 

 
Cho file test.txt chöùa noäi dung  

"Yesterday, all my troubles seemed so far away, 
 Now it looks  as thought they're here to stay. Oh, I believe in yesterday ... " 

Keát quûa chöông trình seõ ra sao khi thöïc hieän leänh töø daáu nhaéc MS-DOS : 

C:\> LOCATE  test.txt  10  

 ? 
 
 
Baøi taäp V 
 
1. Vieát chöông trình xuaát noäi dung cuûa file theo thöù töï töø cuoái trôû veà ñaàu file. 
 
2. Vieát chöông trình thöïc hieän traùo ñoåi vò trí cuûa töøng caëp kyù töï lieân tieáp nhau trong 
file. Bieát raèng soá kyù töï trong file naøy laø soá chaün. Ví duï "abcd" thaønh "badc" 

VI/ Kieåm tra traïng thaùi Nhaäp/Xuaát 

 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

254 

Heä thoáng nhaäp/xuaát C++ löu laïi thoâng tin traïng thaùi keát quûa cuûa moãi taùc vuï 
nhaäp/xuaát. Traïng thaùi hieän haønh cuûa heä thoáng nhaäp/xuaát ñöôïc maõ hoaù thaønh moät soá 
nguyeân. 
 
 
 Teân 

côø   YÙ 

nghiaõ 

 

goodbit 

laø 0 neáu khoâng gaëp loãi 

 

 

 

laø 1 neáu gaëp loãi 

 

eofbit  

laø 0 neáu gaëp vò trí heát file 

 

 

 

laø 1 neáu khoâng gaëp vò trí heát file 

 

failbit   

laø 0 neáu gaëp loãi loaïi non-fatal 

 

 

 

laø 1 neáu khoâng gaëp loãi loaïi non-fatal 

 

badbit  

laø 0 neáu gaëp loãi loaïi fatal 

 

 

 

laø 1 neáu khoâng gaëp loãi loaïi fatal 

 

 

Caùc côø treân laø haèng kieåu lieät keâ ñöôïc ñònh nghiaõ trong ios. 
 

• 

Coù hai caùch ñeå nhaän thoâng tin traïng thaùi nhaäp/xuaát C++. 

Caùch 1  duøng haøm   int  rdstate() ; 
Haøm seõ traû veà giaù trò 

thoâng tin traïng thaùi cuûa caùc côø baùo loãi döôùi daïng moät con 

soá nguyeân. 
 
Caùch 2  duøng moät trong caùc haøm sau : 
   int 

 

bad(); 

return true neáu côø failbit laø 1 

 

 

 

int  eof(); 

return true neáu chöa ñeán cuoái file 

 

 

 

int  good(); 

return true neáu taát caû caùc côø baùo loãi ñeàu coù trò laø 0 

   int 

 

fail(); 

 

 

• 

Khi baét gaëp moät loãi nhaäp/xuaát, söû duïng haøm clear() ñeå xoaù loãi tröôùc khi thöïc thi 

tieáp chöông trình. 

 

 

 

void  clear(

int flags = 0) ; 

 

Neáu flags baèng 0, taát caû caùc côø ñeàu bò xoaù veà trò 0. Ngöôïc laïi, coù theå ñaët giaù 
trò flags ñeå laäp côø theo yù rieâng. 

 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

255 

Ví duï 5.1  

Minh hoaï caùch söû duïng haøm rdstate() .Chöông trình xuaát noäi dung moät 
text file. Neáu gaëp loãi, chöông trình seõ baùo loãi thoâng qua haøm 
checkstatus().  

 
// DISPLAY.CPP 
#include <iostream.h> 
#include <fstream.h> 
 
void checkstatus(ifstream &in); 
 
int main(int argc, char *argv[]

  if(argc != 2) { 
    cout << "Usage: DISPLAY  <filename>\n"; 
    return 1; 
  } 
 
  ifstream in(argv[1]); 
 
  if(!in) { 
    cout << "Cannot open input file.\n"; 
    return 1; 
  } 
 
  char c; 
  while(in.get(c)) { 
    cout << c; 
    checkstatus(in); 
  } 
 
  checkstatus(in);    // check final status.  Error message : EOF encountered 
  in.close(); 
  return 0; 

 
 
 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

256 

/////////////////////////////////////////////////////////////// 
void checkstatus(ifstream &in

  ios::iostate i; 
 
  i = in.rdstate()
   
  if(i & ios::eofbit)  
        cout << "EOF encountered\n"; 
  else  

if(i & ios::failbit) 
      cout << "Non-Fatal I/O error\n"; 

            else  

        if(i & ios::badbit) 

     

              cout << "Fatal I/O error\n"; 


 
Keát quaû chöông trình 
Thoâng baùo loãi EOF encountered xuaát hieän do khi keát thuùc voøng while, laàn thöïc hieän 
cuoái cuøng cuûa haøm checkstatus() töông öùng vôùi traïng thaùi heát file. 
 
 
Ví duï 5.2  

Minh hoaï caùch söû duïng haøm good() ñeå phaùt hieän loãi nhaäp/xuaát . 

 
// PR.CPP 
#include <iostream.h> 
#include <fstream.h> 
 
int main(int argc, char *argv[]

  char ch; 
 
  if(argc != 2) { 
    cout << "PR:  <filename>\n"; 
    return 1; 
  } 
 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

257 

  ifstream  in(argv[1]); 
 
  if(!in) { 
    cout << "Cannot open input file.\n"; 
    return 1; 
  } 
 
  while( !in.eof() ) {  
    in.get(ch); 
 
    // check for error 
    if( ! in.good() && !in.eof()) { 
      cout << "I/O Error...terminating\n"; 
      return 1;    } 
    cout << ch; 
  } 
 
  in.close(); 
  return 0; 

 
Keát quaû chöông trình 
Thoâng baùo loãi "I/O Error...terminating" seõ xuaát hieän khi coù loãi nhaäp/xuaát trong luùc 
xuaát noäi dung cuûa file coù teân <filename> . 
 
 
Baøi taäp VI 
 
1. Haõy theâm phaàn kieåm tra vaø baùo loãi nhaäp/xuaát vaøo caùc chöông trình trong caùc baøi 
taäp phaàn V, chöông 8. 
 
 
 
 
 
 
 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

258 

VII/ Nhaäp/Xuaát theo ñôn ñaët haøng vaø caùc File 

 
Trong C++ do taát caû caùc stream ñeàu ñöôïc xöû lyù nhö nhau, neân moät boä cheøn duøng ñeå 
xuaát thoâng tin ra maøn hình coù theå  duøng ñeå xuaát thoâng tin ra file maø khoâng caàn phaûi 
thay ñoåi gì caû.  
 
Ñaây laø moät trong nhöõng ñaëc tröng quan troïng vaø höõu hieäu cuûa caùch tieáp caän 
nhaäp/xuaát C++. 
 
Caùc boä cheøn vaø boä chieát ñaõ ñöôïc quaù taûi, cuõng nhö caùc boä thao taùc nhaäp/xuaát, coù theå 
duøng cho baát kyø moät stream naøo 

mieãn laø caùc boä naøy ñöôïc vieát moät caùch toång quaùt

 
Do ñoù caàn phaûi toång quaùt hoaù caùc boä cheøn vaø boä chieát hay caùc boä thao taùc nhaäp/xuaát 
baát cöù khi naøo coù theå laøm ñöôïc. 
 
 
Ví duï 6.1

   Quaù taûi caùc toaùn töû << vaø toaùn töû >> trong lôùp coord,  

coù theå duøng chuùng ñeå xuaát thoâng tin ra maøn hình cuõng nhö ra file

 
#include <iostream.h> 
#include <fstream.h> 
class coord { 
  int x, y; 
public: 
  coord(int i, int j) { x = i; y = j; } 
  friend ostream &operator << 

(ostream &stream, coord ob); 

  friend istream  &operator >> (istream &stream, coord &ob); 
}; 
 
ostream &operator<<(ostream &stream, coord ob) 

  stream << ob.x << ' ' << ob.y << '\n'; 
  return stream; 

 
istream &operator>>(istream &stream, coord &ob) 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

259 

  stream >> ob.x >> ob.y; 
  return stream; 

 
int main() 

  coord o1(1, 2), o2(3, 4); 
  ofstream  out("test.txt"); 
 
  if(!out) { 
    cout << "Cannot open output file.\n"; 
    return 1; 
  } 
 
  out << o1 << o2;   

// write to test.txt with the contents : 

1 2 

 

 

 

 

 

 

 

 

 

 

3 4 

  out.close(); 
 
  ifstream in("test.txt"); 
 
  if(!in) { 
    cout << "Cannot open input file.\n"; 
    return 1;  } 
  coord o3(0, 0), o4(0, 0); 
  in >> o3 >> o4;   

// write to objects o3, o4 with the contents : 

1 2 

 

 

 

 

 

 

 

 

 

 

3 4 

  cout << o3 << o4;  

// output to monitors : 

1 2 

 

 

 

 

 

 

 

 

3 4 

  in.close()
  return 0; 

 
 
Ví duï 6.2

   Caùc boä thao taùc nhaäp/xuaát coù theå duøng ñeå xuaát thoâng tin ra maøn hình 

cuõng nhö ra file

 
#include <iostream.h> 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

260 

#include <fstream.h> 
#include <iomanip.h> 
 
// Attention: 
ostream &atn(ostream &stream) 

  stream << "Attention: "; 
  return stream; 

 
// Please note: 
ostream &note(ostream &stream) 

  stream << "Please Note: "; 
  return stream; 

 
int main() 

  ofstream out("test.txt"); 
 
  if(!out) { 
    cout << "Cannot open output file.\n"; 
    return 1; 
  } 
  // write to screen 
  cout << atn << "High voltage circuit\n"; 
  cout << note << "Turn off all lights\n"; 
 
  // write to file 
  out << atn << "High voltage circuit\n"; 
  out << note << "Turn off all lights\n"; 
 
  out.close(); 
  return 0; 

 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

261 

Baøi taäp VII 
 
1. Vôùi moãi chöông trình trong chöông 8, haõy thöïc hieän caùc ñieàu chænh caùc boä cheøn, 
boä chieát vaø caùc boä thao taùc nhaäp/xuaát ñeå chuùng coù theå laøm vieäc ñöôïc vôùi caùc file . 
 
 

VIII/ Nhaäp/Xuaát theo maûng 

 
Ngoaøi nhaäp/xuaát thieát bò chuaån (I/O console) vaø nhaäp/xuaát file, C++ coøn hoå trôï moät 
boä ñaày ñuû caùc haøm duøng daõy kyù töï nhö moät thieát bò nhaäp hoaëc thieát bò xuaát

 
Nhaäp/xuaát theo maûng cuûa C++ meàm deûo vaø höõu hieäu hôn C (caùc haøm sscanf() vaø 
sprintf())  vì noù cho pheùp söû duïng caùc kieåu do ngöôøi duøng ñònh nghóa. 
 
Trong moät soá taøi lieäu khaùc veà C++, nhaäp/xuaát theo maûng coøn ñöôïc goïi laø nhaäp/xuaát 
treân RAM

 
Phaàn naøy chæ khaûo saùt nhöõng ñaëc tröng quan troïng nhaát cuûa nhaäp/xuaát theo maûng. 

• 

Nhaäp/xuaát theo maûng vaãn hoaït ñoäng thoâng qua caùc stream. Caàn naïp file 
strstream.h 

vaøo chöông trình, noù ñònh nghóa 3 lôùp istrstream, ostrstream vaø 

strstream. 

Chuùng taïo ra stream nhaäp, stream xuaát vaø stream nhaäp/xuaát theo 

maûng.  

 
Caùc lôùp treân ñeàu coù chung moät  lôùp cô sôû laø ios, neân taát caû caùc haøm vaø boä thao taùc 
cuûa  istream, ostream vaø iostream  ñeàu coù maët trong istrstream, ostrstream vaø 
strstream.  
Moät soá haøm boå sung sau ñaây seõ lieân keát stream vôùi moät vuøng trong boä nhôù thoâng qua 
buf

 

• 

Daïng toång quaùt cuûa haøm taïo cuûa ostrstream, ñeå söû duïng moät maûng xuaát 

 
 ostrstream 

 

ostr

(char *buf, int size, int mode = ios::out) ;  

 
vôùi ostr laø stream töông öùng vôùi maûng buf. Kích thöôùc cuûa maûng xaùc ñònh bôûi size
Cheá ñoä mode ñöôïc maëc ñònh laø xuaát, nhöng coù theå thay ñoåi baát kyø mode xuaát naøo 
cuûa ios. 
 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

262 

Khi moät maûng ñöôïc môû ñeå cho keát xuaát, caùc kyù töï seõ ñöôïc ñöa vaøo maûng cho ñeán khi 
maûng bò ñaày, maûng khoâng ñöôïc pheùp bò traøn. Moïi caùch ñeå ghi leân maûng ñaày seõ gaây 
loãi nhaäp/xuaát. 
 

• 

Haøm  pcount() traû veà soá löôïng kyù töï ñaõ ñöôïc ghi vaøo trong maûng, keå caû kyù töï 
NULL ñeå keát thuùc. 

int  pcount() 

Khi goïi, caàn gaén teân haøm naøy vôùi moät  stream cuï theå. 
 

• 

Daïng toång quaùt cuûa haøm taïo cuûa istrstream, duøng ñeå môû moät  maûng nhaäp 

 
 istrstream 

 

istr

(const  char *buf) ;  

 
vôùi istr laø stream nhaäp, buf laø moät con troû ñeán maûng ñöôïc duøng laøm maûng nhaäp.  
Khi ñoïc moät maûng, haøm eof() seõ traû veà trò true khi gaëp heát maûng. 
 

• 

Ñeå taïo ra moät  maûng nhaäp/xuaát, duøng haøm taïo cuûa strstream coù daïng  

 
 strstream 

 

iostr

(char *buf, int size, int mode = ios::out) ;  

 
vôùi iostr laø stream nhaäp/xuaát vaø noù söû duïng moät maûng ñöôïc troû bôûi buf. Kích thöôùc 
cuûa maûng xaùc ñònh bôûi size. Ñoái vôùi caùc thao taùc nhaäp/xuaát, cheá ñoä mode phaûi laø  
ios::in 

ios::out

 

• 

Ghi nhôù

, taát caû caùc haøm nhaäp/xuaát trong hai chöông 7 vaø 8 vaãn aùp duïng cho 

nhaäp/xuaát theo maûng, keå caû caùc haøm nhaäp/xuaát nhò phaân vaø ngaãu nhieân .  

 
 
 
Ví duï

 8.1 

chöông trình seõ môû moät maûng xuaát vaø ghi leân maûng 

 
// A short example using array-based output. 
#include <iostream.h> 
#include <strstream.h> 
 
int main() 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

263 

  char buf[255];  

 

 

// output buffer 

 
  ostrstream  ostr(buf, sizeof(buf));  

// open output array 

 
  // output to monitor 
  ostr << "Array-based I/O uses streams just like "; 
  ostr << "'normal' I/O\n" << 100; 
  ostr << ' ' << 123.23 << '\n'; 
   
  // you can use manipulators, too 
  ostr << hex << 100 << ' '; 
  // or format flags 
  ostr.setf(ios::scientific); 
  ostr << dec << 123.23; 
  ostr << endl << ends;    

// ensure that buffer is null-terminated 

 
  // show resultant string 
  cout << buf
 
  return 0; 

 
Keát quaû chöông trình 
Array-based I/O uses streams just like  'normal'  I/O 
100 123.23  
64 01.2323e+02 
 
@ Coù theå thaáy caùc haøm nhaäp/xuaát quaù taûi, caùc boä thao taùc nhaäp/xuaát, caùc haøm thaønh 
phaàn vaø caùc côø ñònh daïng ñeàu coù theå duøng ñöôïc trong nhaäp/xuaát theo maûng. 
 
Chöông trình ñaõ xoaù maûng baèng boä thao taùc ends
Ví duï

 8.2 

chöông trình minh hoaï nhaäp theo maûng 

 
// An example using array-based input. 
#include <iostream.h> 
#include <strstream.h> 
 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

264 

int main() 

  char buf[] = "Hello 100 123.125 a"; 
 
  istrstream  istr(buf);  

 

 

// open input array 

 
  int i; 
  char str[80]; 
  float f; 
  char c; 
 
  istr >> str >> >> >> c

 

// from keyboard 

 
  cout << str << ' ' << i << ' ' << f; 
  cout << ' ' << c << '\n'; 
  return 0; 

 
 

• 

Khi moät maûng nhaäp ñöôïc lieân keát vôùi moät stream, noù raát gioáng nhö moät  file. 

 
Ví duï

 8.3 

chöông trình söû duïng nhaäp/xuaát nhò phaân vaø haøm eof() ñeå  
ñoïc noäi dung cuûa maûng buf 

 
// Demonstrate get() and eof() with array-based I/O.  
#include <iostream.h> 
#include <strstream.h> 
 
int main() 

  char buf[] = "Hello 100 123.125 a"; 
 
  istrstream  istr(buf); 
  char c; 
 
  while(!istr.eof()) { 
    istr.get(c)

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

265 

    if(!istr.eof())  

cout << c; 

  } 
 
  return 0; 

 
 
Ví duï

 8.4 

chöông trình minh hoaï maûng nhaäp/xuaát 

 
// Demonstrate an input/output array. 
#include <iostream.h> 
#include <strstream.h> 
 
int main() 

  char iobuf[255]; 
 
  strstream  iostr(iobuf, sizeof(iobuf), ios::in | ios::out); 
 
  // output to  iobuf[] 
  iostr << "This is a test\n"; 
  iostr << 100 << hex << ' ' << 100 << ends; 
 
  char str[80]; 
  int i; 
 
  // read again from  iobuf[] 
  iostr.getline(str, 79);  

 

// read string up to \n 

  iostr >> dec >> i;   

 

// read 100 

 
  cout << str << ' ' << i << ' '; 
 
  // read continue from  iobuf[] 
  iostr >> hex >> i; 
  cout <<  hex << i; 
  return 0; 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

266 

Baøi taäp VIII 
 
1. Haõy hieäu chænh laïi chöông trình trong ví duï 8.1 chöông 8, sao cho noù in ra soá 
löôïng kyù töï ñöôïc ghi vaøo buf tröôùc khi chöông trình keát thuùc. 
 
2. Vieát chöông trình cho moät öùng duïng nhaäp/xuaát theo maûng ñeå sao cheùp noäi dung 
moät  maûng naøy sang moät  maûng khaùc.  
 
3.  Vieát chöông trình cho moät öùng duïng nhaäp/xuaát theo maûng ñeå chuyeån moät chuoãi 
kyù töï thaønh moät  gía trò soá kieåu daáu chaám ñoäng töông öùng vôùi gía trò maø chuoãi ñoù 
bieåu dieãn .  
 
 
Baøi taäp chöông 8 
 
 
1. Vieát chöông trình taïo ra moät boä thao taùc xuaát ra ba kyù töï tab vaø ñaët ñoä roäng cuûa 
tröôøng laø 20. 
 
2. Vieát chöông trình taïo ra moät boä thao taùc findalpha nhaäp vaø huûy boû caùc kyù töï 
khoâng phaûi laø chöõ caùi. Khi baét gaëp kyù töï chöõ caùi ñaàu tieân, boä thao taùc naøy ñöa traû kyù 
töï vöøa nhaäp trôû laïi stream vaø keát thuùc. 
 
3. Vieát chöông trình sao cheùp moät text file. Trong quaù trình xöû lyù, haõy chuyeån kieåu 
chöõ cuûa taát caû kyù töï sao cho chöõ in hoa bieán thaønh chöõ thöôøng vaø ngöôïc laïi. 
 
4. Vieát chöông trình ñoïc vaøo moät text file vaø in ra soá löôïng chöõ caùi xuaát hieän trong 
file. 
 
5. Chöông trình sau ñaây coù hieäu chænh laïi cuûa lôùp inventory trong chöông 7.  Haõy 
vieát caùc haøm store() vaø retrieve(). Haõy taïo ra moät file toàn kho chöùa vaøi maãu tin. Sau 
ñoù baèng nhaäp/xuaát ngaãu nhieân, haõy cho pheùp ngöôì duøng nhaäp vaøo soá thöù töï cuûa maãu 
tin caàn xem , vaø trình baøy noäi dung cuûa maãu tin ñoù. 
 
#include <iostream.h> 
#include <fstream.h> 
#include <string.h> 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

267 

 
#define SIZE 40 
 
class inventory { 
  char item[SIZE];   // name of item 
  int onhand;   

// number on hand 

  double cost;   

 

// cost of item 

public: 
  inventory(char *i, int o, double c) 
  { 
    strcpy(item, i); 
    onhand = o; 
    cost = c; 
  } 
  void store(fstream &stream); 
  void retrieve(fstream &stream); 
  friend ostream &operator<<(ostream &stream, inventory ob); 
  friend istream &operator>>(istream &stream, inventory &ob); 
}; 
 
ostream &operator<<(ostream &stream, inventory ob) 

  stream << ob.item << ": " << ob.onhand; 
  stream << " on hand at $" << ob.cost << '\n'; 
 
  return stream; 

 
istream &operator>>(istream &stream, inventory &ob) 

  cout << "Enter item name: "; 
  stream >> ob.item; 
  cout << "Enter number on hand: "; 
  stream >> ob.onhand; 
  cout << "Enter cost: "; 
  stream >> ob.cost; 
 

background image

Chöông 8   Nhaäp / Xuaát  C++ 

 

naâng cao

 

                                                               

 

 

 

268 

  return stream; 

 
// define the functions here 
// void store(fstream &stream)  

 ... 

 
//  void retrieve(fstream &stream) 

 ... 

 
 
6. Haõy vieát chöông trình taïo ra lôùp stack  chöùa caùc kyù töï vaø löu stack naøy vaøo moät 
file. 
Xuaát noäi dung file naøy ra maøn hình. 
 
 

background image

 

 

 
Chöông 9   
 
 

Tính ña hình 

 
 
 
 
 
 
 
 
 
 

• 

Con troû  vaø Lôùp daãn xuaát  

 

• 

Daãn nhaäp caùc haøm aûo 

 

• 

Caùc haøm aûo thuaàn tuùy 

 

• 

AÙp duïng ña hình 

 

 
 

 
 
 
 
 

 
 
 
 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

270 

 

I/ Con troû vaø Lôùp daãn xuaát 

 
1/ Khaùi nieäm 
Tính ña hình

 (polymorphism) ñöôïc hoå trôï baèng hai caùch khaùc nhau trong C++ . 

 
Caùch 1, ña hình ñöôïc hoå trôï khi bieân dòch chöông trình (compiler)  thoâng qua vieäc quaù 
taûi caùc haøm vaø toaùn töû

 
Caùch 2, ña hình ñöôïc hoå trôï ôû thôøi ñieåm thöïc thi chöông trình (run-time) thoâng qua 
caùc haøm aûo

. Caùch naøy giuùp laäp trình vieân linh ñoäng hôn. 

 

• 

Cô sôû cuûa haøm aûo vaø ña hình khi thöïc thi chöông trình laø caùc con troû cuûa lôùp 

daãn xuaát. 

 
Chöông 3 coù khaûo saùt veà con troû, moät ñaëc tính môùi cuûa con troû seõ ñöôïc khaûo saùt 
trong chöông naøy. Neáu p laø moät con troû tôùi lôùp cô sôû, thì coù theå söû duïng p ñeå troû tôùi 
baát kyø lôùp naøo ñöôïc suy ra töø lôùp cô sôû

 
Chaúng haïn, coù hai lôùp cô sôû base vaø lôùp daãn xuaát derived keá thöøa base, caùc phaùt bieåu 
sau ñeàu ñuùng 
 
base *p;  

 

// base class pointer 

 
base base_ob;  

 

// object of type base 

derived derived_ob;  

// object of type derived 

 
// p can, of course, point to base objects 
p = &base_ob;  

// p points to base object 

 
// p can also point to derived objects without error 
p = &derived_ob;   // p points to derived object 
 
Moät con troû cuûa lôùp cô sôû coù theå troû tôùi baát kyø lôùp daãn xuaát naøo cuûa lôùp cô sôû maø 
khoâng gaây ra baùo loãi khaùc kieåu

. Song chæ coù theå truy caäp ñöôïc caùc thaønh phaàn maø lôùp 

daãn xuaát  ñöôïc keá thöøa töø lôùp cô sôû

. Bôûi vì con troû cuûa lôùp cô sôû chæ bieát lôùp cô sôû maø 

thoâi, noù khoâng bieát gì nhöõng thaønh phaàn ñöôïc theâm vaøo bôûi lôùp daãn xuaát. 
 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

271 

 

• 

Moät con troû cuûa lôùp daãn xuaát khoâng theå duøng ñeå truy caäp moät ñoái töôïng cuûa lôùp 

cô sôû

. (Vieäc söû duïng linh hoaït kieåu coù theå duøng ñeå khaéc phuïc haïn cheá noùi treân, 

nhöng noù khoâng ñöôïc khuyeán khích söû duïng) 

 
Caùc pheùp toaùn soá hoïc treân con troû lieân quan ñeán kieåu döõ lieäu maø con troû ñoù ñöôïc 
khai baùo ñeå troû ñeán. Do ñoù, neáu con troû ñeán moät ñoái töôïng lôùp daãn xuaát, roài taêng noäi 
dung con troû leân 1

. Ñieàu naøy khoâng laøm cho con troû chæ ñeán ñoái töôïng môùi cuûa lôùp 

daãn xuaát, maø noù seõ chæ ñeán ñoái töôïng môùi cuûa lôùp cô sôû.  
 
 
Ví duï 1.1

 

Duøng con troû cuûa lôùp cô sôû ñeå truy caäp ñeán lôùp daãn xuaát. 

 
// Demonstrate pointer to derived class. 
#include <iostream.h> 
 
class base { 
  int x; 
public: 
  void setx(int i) { x = i; } 
  int getx() { return x; } 
}; 
 
class derived : public base { 
  int y; 
public: 
  void sety(int i) { y = i; } 
  int gety() { return y; } 
}; 
 
int main() 

  base *p;    

// pointer to base type 

  base  b_ob;   

// object of base 

  derived  d_ob;  

// object of derived 

 
  // use p to access base object 
  p = &b_ob

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

272 

 

  p->setx(10);  

 

// access base object 

  cout << "Base object x: " << p->getx() << '\n'; 
 
  // use p to access derived object 
  p = &d_ob;  

 

// point to derived object 

  p->setx(99);  

 

// access derived object 

 
  // can't use p to set y, so do it directly 
  d_ob.sety(88); 
  cout << "Derived object x: " << p->getx() << '\n'; 
  cout << "Derived object y: " << d_ob.gety() << '\n'; 
 
  return 0; 

 
 

II/ Daãn nhaäp haøm aûo (virtual function) 

 
1/ Khaùi nieäm 
Haøm aûo

 laø haøm thaønh phaàn cuûa moät lôùp, noù ñöôïc khai baùo ôû lôùp cô sôû vaø ñöôïc ñònh 

nghiaõ laïi trong lôùp daãn xuaát. 
 
Khai baùo haøm aûo baét ñaàu baèng töø khoaù virtual . Moät lôùp coù chöùa haøm aûo ñöôïc keá 
thöøa, lôùp daãn xuaát seõ taùi ñònh nghiaõ haøm aûo ñoù cho chính mình. 
 

• 

Caùc haøm aûo trieån khai yù töôûng chuû ñaïo cuûa ña hình laø "moät giao dieän cho nhieàu 

phöông thöùc

". Haøm aûo beân trong moät lôùp cô sôû ñònh nghiaõ hình thöùc giao tieáp ñoái 

vôùi haøm ñoù.  

 
Vieäc taùi ñònh cuûa haøm aûo ôû lôùp daãn xuaát laø thi haønh caùc taùc vuï cuûa haøm lieân quan ñeán 
chính lôùp daãn xuaát ñoù

. Noùi caùch khaùc, taùi ñònh caùc haøm aûo chính laø taïo ra caùc phöông 

thöùc cuï theå. Haøm aûo taùi ñònh ôû lôùp daãn xuaát khoâng caàn söû duïng töø khoaù virtual. 
 
  
 
 

• 

Nguyeân lyù laøm vieäc cuûa ña hình trong khi thöïc thi chöông trình 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

273 

 

Haøm aûo ñöôïc goïi thöïc thi gioáng nhö caùc haøm thaønh phaàn bình thöôøng cuûa lôùp. Tuy 
nhieân, khi goïi haøm aûo baèng con troû, vieäc hoå trôï tính ña hình trong khi thöïc thi chöông 
trình seõ xaûy ra. 
 
Khi moät con troû troû ñeán moät lôùp daãn xuaát coù chöùa haøm aûo vaø haøm aûo naøy ñöôïc goïi 
baèng con troû thì trình bieân dòch seõ xaùc ñònh phieân baûn naøo cuûa haøm ñoù seõ ñöôïc thöïc 
thi. Do ñoù neáu coù hai hay nhieàu lôùp daãn xuaát cuûa moät lôùp cô sôû naøo ñoù, vaø chuùng ñeàu 
coù chöùa haøm aûo, thì con troû cuûa lôùp cô sôû coù theå troû ñeán caùc ñoái töôïng khaùc nhau cuûa 
lôùp daãn xuaát noùi treân, töùc laø coù theå goïi ñeán nhieàu phieân baûn khaùc nhau cuûa caùc haøm 
aûo. 
 

• 

Moät lôùp coù chöùa haøm aûo ñöôïc goïi laø lôùp ña hình

 
Ví duï 2.1 
 
// A simple example using a virtual function. 
#include <iostream.h> 
 
class base { 
public: 
  int i; 
  base(int x) { i = x; } 
  virtual void func() 
  { 
    cout << "Using base version of func(): "; 
    cout << i << '\n'; 
  } 
}; 
 
class derived1 : public base { 
public: 
  derived1(int x) : base(x) {} 
  void func()  
  { 
    cout << "Using derived1's version of func(): "; 
    cout << i * i << '\n'; 
  } 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

274 

 

}; 
 
class derived2 : public base { 
public: 
  derived2(int x) : base(x) {} 
  void func()  
  { 
    cout << "Using derived2's version of func(): "; 
    cout << i i << '\n'; 
  } 
}; 
 
int main() 

  base *p; 
  base  ob(10);   
  derived1  d_ob1(10);    
  derived2  d_ob2(10);  
 
  p = &ob; 
  p->func();   // use base's func() 
 
  p = &d_ob1; 
  p->func();   // use derived1's func() 
 
  p = &d_ob2; 
  p->func();   // use derived2's func() 
 
  return 0; 

 
@ Kieåu cuûa ñoái töôïng ñöôïc troû ñeán seõ xaùc ñònh phieân baûn naøo cuûa haøm aûo ñöôïc thöïc 
thi thoâng qua caùch goïi haøm baèng con troû. Ñieàu naøy chæ xaùc ñònh ñöôïc trong luùc run-
time. 
 
 
2/ Haøm aûo vaø quaù taûi haøm 

Giaûi thích keát quûa chöông trình ? 
 
Using base version of func() :  10 
Using derived1's version of func() :  100 
Using derived2's version of func() :  20 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

275 

 

Vieäc taùi ñònh haøm aûo trong moät lôùp daãn xuaát coù töông töï nhö quaù taûi haøm khoâng ? 
Caâu traû lôøi laø khoâng. 
 

 

Quaù taûi haøm 

Haøm aûo 

Soá löôïng ñoái soá  

Cho pheùp khaùc bieät  

Phaûi gioáng nhau 

Kieåu döõ lieäu cuûa ñoái soá  

Cho pheùp khaùc bieät 

Phaûi gioáng nhau 

Haøm thaønh phaàn cuûa lôùp 

Khoâng baét buoäc 

Baét buoäc 

Haøm taïo 

Ñöôïc pheùp 

Khoâng ñöôïc 

Haøm huûy 

Khoâng ñöôïc 

Coù theå 

Vò trí 

 

 

 
Vieäc taùi ñònh haøm aûo trong moät lôùp daãn xuaát coøn ñöôïc goïi laø gaùn thöù töï öu tieân cao 
hôn cho haøm ñoù

 
3/ Caùc haøm aûo ñöôïc phaân caáp theo thöù töï keá thöøa

Neáu lôùp daãn xuaát khoâng taùi ñònh haøm aûo naøo ñoù thì lôùp naøy seõ söû duïng phieân baûn 
haøm cuûa lôùp cô sôû.  
 
Ví duï 2.2 
// Virtual functions are hierarchical. 
#include <iostream.h> 
 
class base { 
public: 
  int i; 
  base(int x) { i = x; } 
  virtual void func() 
  { 
    cout << "Using base version of func(): "; 
    cout << i << '\n'; 
  } 
}; 
 
class  derived1 : public base { 
public: 
  derived1(int x) : base(x) {} 
  void func()  

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

276 

 

  { 
    cout << "Using derived1's version of func(): "; 
    cout << i*i << '\n'; 
  } 
}; 
 
class  derived2 : public base { 
public: 
  derived2(int x) : base(x) {} 
  // derived2 does not override func() 
}; 
 
int main() 

  base *p; 
  base  ob(10);   
  derived1  d_ob1(10);    
  derived2  d_ob2(10);  
  p = &ob; 
  p->func();   // use base's func() 
 
  p = &d_ob1; 
  p->func();   // use derived1's func() 
 
  

p = &d_ob2; 

  p->func();   // use base's func() 
 
  return 0; 

 
 
4/ Caùch ñaùp öùng cuûa haøm aûo ñoái vôùi moät bieán coá ngaãu nhieân ôû thôøi ñieåm run-
time 
 
Ví duï 2.3 
//  This example illustrates how a virtual function can be used to respond to random  
//  events occurring at run time. 

Keát quûa chöông trình 
 
Using base version of func() :  10 
Using derived1's version of func() :  100 
Using base version of func() :  10 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

277 

 

 
#include <iostream.h> 
#include <stdlib.h> 
 
class base { 
public: 
  int i; 
  base(int x) { i = x; } 
  virtual void func() 
  { 
    cout << "Using base version of func(): "; 
    cout << i << '\n'; 
  } 
}; 
 
 
class  derived1 : public base { 
public: 
  derived1(int x) : base(x) {} 
  void func()   { 
    cout << "Using derived1's version of func(): "; 
    cout << i*i << '\n'; 
  } 
}; 
 
class  derived2 : public base { 
public: 
  derived2(int x) : base(x) {} 
  void func() 

  { 

    cout << "Using derived2's version of func(): "; 
    cout << i+i << '\n'; 
  } 
}; 
 
 
 
int main() 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

278 

 


  base *p; 
  derived1  d_ob1(10);    
  derived2  d_ob2(10);  
  int i, j; 
 
  for(i=0; i<10; i++) { 
    j = rand(); 
    if( ( j % 2) )  

p = &d_ob1;   

// if odd use d_ob1 

    else  

 

p = &d_ob2;   

// if even use d_ob2 

    p->func();   

 

 

 

// call appropriate function 

  } 
 
  return 0; 

 
Vieäc choïn löïa ñeå thöïc thi phieân baûn haøm aûo naøo (haøm func() cuûa lôùp derived1 hay 
haøm func() cuûa lôùp derived2)  chæ ñöôïc quyeát ñònh trong luùc run-time. Ñieàu naøy 
khoâng theå naøo thöïc hieän ñöôïc ôû thôøi ñieåm bieân dòch chöông trình. 
 
 
5/ Söû duïng haøm aûo ñeå trieån khai caùch thöùc giao dieän 
 
Ví duï 2.4 

 

// Use virtual function to define interface. 
 
#include <iostream.h> 
 
class area { 
  double dim1, dim2;  

 

// dimensions of figure 

public: 
  void setarea(double d1, double d2)  { 
    dim1 = d1; 
    dim2 = d2; 
  } 
 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

279 

 

  void getdim(double &d1, double &d2)  { 
    d1 = dim1; 
    d2 = dim2; 
  } 
 
  virtual double getarea()  {  
    cout << "You must override this function\n"; 
    return 0.0; 
  } 
}; 
 
 
class rectangle : public area { 
public: 
  double getarea()   { 
    double d1, d2; 
    getdim(d1, d2); 
    return d1 * d2; 
  } 
}; 
 
class  triangle : public area { 
public: 
 
  double getarea()  { 
    double d1, d2; 
   
    getdim(d1, d2); 
    return 0.5 * d1 * d2; 
  } 
}; 
 
 
int main() 

  area *p; 
  rectangle r; 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

280 

 

  triangle t; 
 
  r.setarea(3.3, 4.5); 
  t.setarea(4.0, 5.0); 
 
  p = &r
  cout << "Rectangle has area: " <<  p->getarea() << '\n'; 
 
  p = &t
  cout << "Triangle has area: " <<  p->getarea() << '\n'; 
 
  return 0; 

 
@ Vieäc khai baùo haøm aûo trong  lôùp cô sôû area chæ mang tính chaát giöõ choã, khoâng 
thöïc hieän moät coâng vieäc cuï theå naøo. 
 
 
Baøi taäp II 
 
1. Vieát chöông trình taïo ra moät lôùp cô sôû num löu tröõ moät soá nguyeân , vaø haøm aûo cuûa 
lôùp laø shownum() coù daïng  
 

class  num { 

 public 

 

 

int  i ; 

 

 

num(int x) { i = x;} 

 

 

virtual void shownum() { cout << i << '\n';} 

}; 

 
Haõy taïo hai lôùp daãn xuaát cuûa num coù teân laø outhex vaø outoct. Haõy taùi ñònh caùc haøm 
aûo cuûa hai lôùp daãn xuaát treân ñeå chuùng xuaát ra soá nguyeân döôùi daïng soá hec vaø soá oct. 
 
2. Vieát chöông trình taïo ra moät lôùp cô sôû distance löu khoaûng caùch giöõa hai ñieåm vôùi 
kieåu döõ lieäu double.  
 

class distance { 

 public 

  double 

 

d; 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

281 

 

 

 

distance (double f) { d = f;} 

 

 

virtual void trav_time() { 
 

// define here ... 

 

  

}; 

 
Taïo haøm aûo trav_time() cuûa lôùp distance xuaát ra khoaûng thôøi gian caàn thieát ñeå ñi qua 
khoaûng caùch naøy. Giaû söû raèng ñôn vò chieàu daøi laø mile vaø vaän toác di chuyeån laø 60 
mile/hours. 
 
Haõy taïo lôùp daãn xuaát metric töø lôùp distance, vôùi haøm aûo trav_time() in ra khoaûng 
thôøi gian caàn thieát ñeå ñi qua khoaûng caùch treân, tuy nhieân luùc naøy ñôn vò chieàu daøi laø 
km vaø vaän toác laø 100km/giôø. 
 
 

III/ Caùc haøm aûo thuaàn tuùy (pure virtual function) 

 
Moät tröôøng hôïp khaù phoå bieán khi lôùp cô sôû töï noù khoâng phaûi laø moät lôùp hoaøn chænh
luùc ñoù haøm aûo ñöôïc khai baùo giöõ choã chöù khoâng thöïc hieän coâng vieäc cuï theå. Lôùp cô 
sôû naøy chæ cung caáp moät boä khung goàm caùc haøm vaø bieán vaø ñeå daønh cho caùc lôùp daãn 
xuaát caùc phaàn ñònh nghóa coøn laïi. Caùc lôùp daãn xuaát phaûi taùi ñònh taát caû caùc haøm aûo 
khai baùo trong lôùp cô sôû ñoù. Ñeå ñaûm baûo cho ñieàu naøy, C++  hoå trôï moät coâng cuï goïi 
laø haøm aûo thuaàn tuùy. 
 

• 

Haøm aûo thuaàn tuùy

 khoâng coù moät ñònh nghiaõ naøo lieân quan ñeán lôùp cô sôû. Noù chæ 

coù daïng haøm maø thoâi, caùch khai baùo 

 
 

virtual

  <type>  func-name(arg-list) = 0 ; 

Haøm ñöôïc gaùn trò zero vôùi muïc ñích thoâng baùo cho trình bieân dòch bieát laø khoâng coù 
gì trong haøm laø lieân quan ñeán lôùp cô sôû.  
 
Khi haøm aûo laø moät haøm aûo thuaàn tuùy, noù buoäc caùc lôùp daãn xuaát phaûi taùi ñònh noù, neáu 
khoâng trình bieân dòch seõ baùo loãi luùc bieân dòch chöông trình

 

• 

Neáu moät lôùp coù chöùa haøm aûo thuaàn tuùy, lôùp ñoù ñöôïc goïi laø lôùp tröøu töôïng

Lôùp tröøu töôïng ñöôïc taïo ra vôùi muïc ñích phaûi ñöôïc keá thöøa, khoâng ñöôïc vaø khoâng 
theå taïo ra ñeå toàn taïi ñôn ñoäc.  

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

282 

 

Tuy nhieân, coù theå taïo ra moät con troû ñeán lôùp tröøu töôïng bôûi vì ñieàu naøy caàn thieát ñeå 
hoå trôï cho ña hình trong khi run-time

. Ñieàu naøy cuõng cho pheùp tham chieáu ñeán moät 

lôùp tröøu töôïng. 
 

• 

Khi moät haøm aûo ñöôïc keá thöøa, baûn chaát aûo cuûa noù cuõng ñöôïc keá thöøa

.  

Ñieàu naøy coù nghiaõ laø khi moät lôùp daãn xuaát keá thöøa haøm aûo töø lôùp cô sôû, moät lôùp 
daãn xuaát thöù hai laïi keá thöøa lôùp daãn xuaát thöù nhaát, haøm aûo coù theå ñöôïc ñònh nghiaõ 
laïi ôû lôùp daãn xuaát thöù hai 

(cuõng nhö noù ñöôïc ñònh nghiaõ laïi ôû lôùp daãn xuaát thöù 

nhaát). 

 
 
Ví duï 3.1

 

Taïo moät lôùp tröøu töôïng 

#include <iostream.h> 
 
class  area { 
  double dim1, dim2;  

 

// dimensions of figure 

public: 
  void setarea(double d1, double d2)  { 
    dim1 = d1; 
    dim2 = d2; 
  } 
  void getdim(double &d1, double &d2)  { 
    d1 = dim1; 
    d2 = dim2; 
  } 
  virtual double getarea() = 0

;   // pure virtual function 

}; 
 
class  rectangle : public area { 
public: 
  double getarea()    { 
    double d1, d2; 
   
    getdim(d1, d2); 
    return d1 * d2; 
  } 
}; 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

283 

 

class  triangle : public area { 
public: 
  double getarea()   { 
    double d1, d2; 
   
    getdim(d1, d2); 
    return 0.5 * d1 * d2; 
  } 
}; 
 
int main() 

  area *p; 

 

 

  rectangle r; 
  triangle t; 
 
  r.setarea(3.3, 4.5); 
  t.setarea(4.0, 5.0); 
 
  p = &r ; 
  cout << "Rectangle has area: " << p->getarea() << '\n'; 
 
  p = &t ; 
  cout << "Triangle has area: " << p->getarea() << '\n'; 
 
  return 0; 

 
Ví duï 3.2

 

Minh hoaï vieäc baûo toàn baûn chaát aûo cuûa haøm khi noù ñöôïc keá thöøa. 

// Virtual functions retain their virtual nature when inherited. 
#include <iostream.h> 
class base { 
public: 
  virtual void func()  { 
    cout << "Using base version of func()\n"; 
  } 
}; 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

284 

 

class  derived1 : public base { 
public: 
  void func()   { 
    cout << "Using derived1's version of func()\n"; 
  } 
}; 
 
// Derived2 inherits derived1. 
class  derived2 : public derived1 { 
public: 
  void func() 
    cout << "Using derived2's version of func()\n"; 
  } 
}; 
 
int main() 

  base *p; 
  base  ob; 
  derived1  d_ob1; 
  derived2  d_ob2; 
 
  p = &ob
  p->func();   // use base's func() 
 
  p = &d_ob1
  p->func();   // use derived1's func() 
 
  p = &d_ob2
  p->func();   // use derived2's func() 
  return 0; 

 
 
 
 
 

Keát quaû chöông trình ? 
 
 
 
Ñieàu gì xaûy ra khi caû hai lôùp daãn xuaát ñeàu 
khoâng taùi ñònh haøm aûo func() ? 

 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

285 

 

Baøi taäp III 
 
1. Haõy taïo ra moät ñoái töôïng cho lôùp area trong ví duï 3.1 chöông 9, ñieàu gì seõ xaûy ra 

 
2. Trong ví duï 3.2 chöông 9, thöû xoaù phaàn taùi ñònh haøm aûo func() cuûa lôùp derived2, 
roài cho truy caäp d_ob2. Keát quûa cuûa chöông trình theá naøo ? 
 
3. Taïi sao khoâng  theå taïo ra moät ñoái töôïng thuoäc lôùp tröøu töôïng ? 
 
 

IV/ Aùp duïng ña hình  

Taïi sao caàn söû duïng ña hình ? 
 
1/ Ña hình raát quan troïng vì noù ñôn giaûn hoaù caùc heä thoáng phöùc taïp

 

• 

Ña hình laø moät quaù trình aùp duïng moät giao dieän cho hai hay nhieàu tröôøng hôïp 

töông töï nhau (nhöng khaùc bieät veà maët kyõ thuaät), noù trieån khai tö töôûng "moät 
giao dieän cho nhieàu phöông thöùc

" .  

 
Moät giao dieän hay vaø ñôn giaûn ñöôïc duøng ñeå truy caäp ñeán moät soá caùc hoaït ñoäng coù 
lieân heä vôùi nhau nhöng khaùc nhau, vaø laøm maát ñi söï phöùc taïp giaû taïo cuûa heä thoáng 
caùc hoaït ñoäng naøy. 
 

• 

Ña hình laøm cho moái quan heä luaän lyù giöõa caùc hoaït ñoäng töông töï nhau ñöôïc trôû 

neân roõ raøng hôn, ño ñoù noù giuùp cho laäp trình vieân deã daøng hôn trong vieäc ñoïc 
hieåu vaø baûo trì chöông trình. 

 
Moät khi caùc hoaït ñoäng coù lieân quan vôùi nhau ñöôïc truy caäp baèng duy nhaát moät giao 
dieän, giuùp seõ nhôù hôn. Giao dieän ñoà hoaï treân heä ñieàu haønh Windows hoaëc Macintosh 
laø moät ñieån hình. 
 
 
2/ Khaùi nieäm veà lieân keát 
 
Lieân keát

 (binding) lieân quan ñeán OOP vaø ngoân ngöõ C++. Coù hai khaùi nieäm : 

 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

286 

 

• 

Lieân keát sôùm 

(early binding) gaén lieàn vôùi nhöõng bieán coá coù theå xaùc ñònh ôû thôøi 

ñieåm bieân dòch chöông trình

. Ñaëc bieät, lieân keát sôùm lieân quan ñeán caùc goïi haøm 

ñöôïc xöû lyù trong luùc bieân dòch bao goàm : 

 

- Caùc haøm thoâng thöôøng 

 

- Caùc haøm ñöôïc quaù taûi 

 

- Caùc haøm thaønh phaàn khoâng phaûi laø haøm aûo 

 

- Caùc haøm friend 

 
Taát caû caùc thoâng tin veà ñòa chæ caàn thieát cho vieäc goïi caùc haøm treân ñöôïc xaùc ñònh roõ 
raøng trong luùc bieân dòch. 
 
Öu ñieåm : goïi caùc haøm lieân keát sôùm laø kieåu goïi haøm nhanh nhaát. 
Nhöôïc ñieåm : thieáu tính linh hoaït. 
 

• 

Lieân keát muoän 

(late binding) gaén lieàn vôùi nhöõng bieán coá xuaát hieän trong luùc 

thöïc thi chöông trình (run-time)

.  

 
Khi goïi caùc haøm lieân keát  muoän, ñiaï chæ cuûa haøm ñöôïc goïi chæ bieát ñöôïc khi run-time.  
 
Trong C++, haøm aûo laø moät ñoái töôïng lieân keát  muoän. Chæ khi run-time, haøm aûo ñöôïc 
truy caäp baèng con troû cuûa lôùp cô sôû, chöông trình môùi xaùc ñònh kieåu cuûa ñoái töôïng bò 
troû vaø bieát ñöôïc phieân baûn naøo cuûa haøm aûo ñöôïc thöïc thi. 
 
Öu ñieåm : tính linh hoaït cuûa noù ôû thôøi gian run-time, ñieàu naøy giuùp cho chöông trình 
goïn gaøng vì khoâng coù nhöõng ñoaïn chöông trình xöû lyù caùc bieán coá ngaãu nhieân trong 
khi thöïc thi. 
 
Nhöôïc ñieåm : chaäm hôn so vôùi lieân keát sôùm, do phaûi qua nhieàu giai ñoaïn trung gian 
keøm theo vieäc goïi thöïc thi moät haøm lieân keát muoän. 
 
 
Moãi loaïi lieân keát ñeàu coù nhöõng öu khuyeát ñieåm rieâng cuûa noù, neân phaûi caân nhaéc ñeå 
quyeát ñònh tình huoáng thích hôïp ñeå söû duïng hai loaïi lieân keát noùi treân. 
 
 
 
Ví duï 4.1 

Minh hoïa tö töôûng "moät giao dieän cho nhieàu phöông thöùc" .  

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

287 

 

 
// Demonstrate virtual functons. 
#include <iostream.h> 
#include <stdlib.h> 
#include <ctype.h> 
 
class list { 
public: 
  list *head;   // pointer to start of list 
  list *tail;   // pointer to end of list  
  list *next;   // pointer to next item 
  int num;   // value to be stored 
 
  list() { head = tail = next = NULL; } 
  virtual void store(int i) = 0; 
  virtual int retrieve() = 0; 
}; 
 
// Create a queue type list. 
class  queue : public list { 
public: 
  void store(int i); 
  int retrieve(); 
}; 
 
void queue::store(int i) 

  list *item
 
  item = new queue; 
  if(!item) { 
    cout << "Allocation error.\n"; 
    exit(1); 
  } 
  item->num = i; 
 
  // put on end of list 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

288 

 

  if(tail) tail->next = item; 
  tail = item; 
  item->next = NULL; 
  if(!head) head = tail; 

 
int queue::retrieve() 

  int i; 
  list *p
 
  if(!head) { 
    cout << "List empty.\n"; 
    return 0; 
  } 
 
  // remove from start of list 
  i = head->num; 
  p = head; 
  head = head->next; 
  delete p; 
  return i; 

 
// Create a stack type list. 
class  stack : public list { 
public: 
  void store(int i); 
  int retrieve(); 
}; 
 
void stack::store(int i) 

  list *item

 
  item = new stack; 
  if(!item) { 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

289 

 

    cout << "Allocation error.\n"; 
    exit(1); 
  } 
  item->num = i; 
 
  // put on front of list for stack-like operation 
  if(head) item->next = head; 
  head = item; 
  if(!tail) tail = head; 

int stack::retrieve() 

  int i; 
  list *p
 
  if(!head) { 
    cout << "List empty.\n"; 
    return 0; 
  } 
 
  // remove from start of list 
  i = head->num; 
  p = head; 
  head = head->next; 
  delete p; 
 
  return i; 

 
int main() 

  list *p
 
  // demonstrate queue 
  queue  q_ob
  p = &q_ob;  

// point to queue 

  p->store(1); 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

290 

 

  p->store(2); 
  p->store(3); 
 
  cout << "Queue: "; 
  cout << p->retrieve(); 
  cout << p->retrieve(); 
  cout << p->retrieve(); 
 
  cout << '\n'; 
 
 
  // demonstrate stack 
  stack  s_ob
  p = &s_ob; // point to stack 
 
  p->store(1); 
  p->store(2); 
  p->store(3); 
 
  cout << "Stack: "; 
  cout << p->retrieve(); 
  cout << p->retrieve(); 
  cout << p->retrieve(); 
 
  cout << '\n'; 
  return 0; 

 
 
Ví duï 4.2 

Duøng ña hình ñeå xöû lyù caùc bieán coá ngaãu nhieân.  

 

 

Söû duïng caùc khai baùo vaø ñònh nghiaõ lôùp ôû ví duï 4.1 . 

 
int main() 

  list *p
  stack  s_ob; 
  queue q_ob; 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

291 

 

  char ch; 
  int i; 
 
  for(i=0; i<10; i++) { 
    cout << "Stack or Queue? (S/Q): "; 
    cin >> ch; 
    ch = tolower(ch); 
    if(ch=='q')  

 

p = &q_ob

    else  

p = &s_ob

    p->store(i); 
  } 
  cout << "Enter T to terminate\n"; 
  for(;;) { 
    cout << "Remove from Stack or Queue? (S/Q): "; 
    cin >> ch; 
    ch = tolower(ch); 
    if(ch=='t') break; 
    if(ch=='q')  

p = &q_ob

    else  

p = &s_ob

    cout << p->retrieve() << '\n'; 
  } 
 
  cout << '\n'; 
  return 0; 

 

• 

Trong HÑH Windows vaø OS2, thoâng qua giao dieän ngöôøi duøng giao tieáp vôùi moät 

chöông trình baèng caùch gôûi ñeán chöông trình caùc messages. Nhöõng message naøy 
ñöôïc phaùt sinh moät caùch ngaãu nhieân 

vaø chöông trình cuûa baïn phaûi ñaùp öùng caùc 

message naøy moãi khi nhaän ñöôïc noù. Do ñoù, ña hình giuùp thöïc thi chöông trình raát 
höõu hieäu cho caùc chöông trình ñöôïc vieát ñeå söû duïng trong caùc HÑH noùi treân. 

 
Ví duï 4.3 

Moät chöông trình ñôn giaûn nhaát treân Windows, xuaát ra maøn hình  

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

292 

 

moät khung cöûa soå chöùa noäi dung " Hello, Windows 98 ! " 

 
#include <windows.h> 
 
LRESULT CALLBACK  WndProc (HWND, UINT, WPARAM, LPARAM) ; 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                    PSTR szCmdLine, int iCmdShow) 

     static TCHAR szAppName[] = TEXT ("HelloWin") ; 
     HWND          

hwnd ; 

     MSG           

msg ; 

     WNDCLASS     wndclass ; 
 
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ; 
     wndclass.lpfnWndProc   

= WndProc ; 

     wndclass.cbClsExtra      

= 0 ; 

     wndclass.cbWndExtra    

= 0 ; 

     wndclass.hInstance        

= hInstance ; 

     wndclass.hIcon            

= LoadIcon (NULL, IDI_APPLICATION) ; 

     wndclass.hCursor          

= LoadCursor (NULL, IDC_ARROW) ; 

     wndclass.hbrBackground  

= (HBRUSH) GetStockObject (WHITE_BRUSH) ; 

     wndclass.lpszMenuName   

= NULL ; 

     wndclass.lpszClassName  

= szAppName ; 

 
     if (!RegisterClass (&wndclass))     { 
          MessageBox (NULL, TEXT ("This program requires Windows NT!"),  
                      szAppName, MB_ICONERROR) ; 
          return 0 ; 
     } 
      
     hwnd = CreateWindow (szAppName,                    // window class name 
                          TEXT ("The Hello Program"),   

// window caption 

                          WS_OVERLAPPEDWINDOW,          // window style 
                          CW_USEDEFAULT,                 

// initial x position 

                          CW_USEDEFAULT,                 

// initial y position 

                          CW_USEDEFAULT,                 

// initial x size 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

293 

 

                          CW_USEDEFAULT,                 

// initial y size 

                          NULL,                          

 

// parent window handle 

                          NULL,                          

 

// window menu handle 

                          hInstance,                     

 

// program instance handle 

                          NULL) ;                        

 

// creation parameters 

      
     ShowWindow (hwnd, iCmdShow) ; 
     UpdateWindow (hwnd) ; 
      
     while (GetMessage (&msg, NULL, 0, 0))     { 
          TranslateMessage (&msg) ; 
          DispatchMessage (&msg) ; 
     } 
     return msg.wParam ; 

 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////LRESULT CALLBACK WndProc  (HWND hwnd, UINT message, WPARAM 
wParam, LPARAM lParam) 

     HDC         hdc ; 
     PAINTSTRUCT  ps ; 
     RECT        rect ; 
      
     switch (message
     { 
     case WM_CREATE : 
          PlaySound 

(TEXT("hellowin.wav"), 

NULL, 

SND_FILENAME 

SND_ASYNC) ; 
          return 0 ; 
           
     case WM_PAINT : 
          hdc = BeginPaint (hwnd, &ps) ; 
           
          GetClientRect (hwnd, &rect) ; 
           
          DrawText (hdc, TEXT (" Hello, Windows 98 ! "), -1, &rect, 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

294 

 

                    DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; 
           
          EndPaint (hwnd, &ps) ; 
          return 0 ; 
         
     case WM_DESTROY : 
          PostQuitMessage (0) ; 
          return 0 ; 
     } 
 
     return DefWindowProc (hwnd, message, wParam, lParam) ; 

 
 
Baøi taäp IV 
 
1.  Theâm vaøo chöông trình ôû ví duï 4.1 moät kieåu danh saùch lieân keát, laø loaïi danh saùch 
coù chöùc naêng xeáp caùc phaàn töû theo thöù töï taêng daàn moãi khi theâm phaàn töû môùi vaøo 
danh saùch. Ñaët teân cho lôùp naøy laø sorted thöøa keá lôùp cô sôû list.  
Lôùp sorted chöùa hai haøm chung laø  
- void store(int i) coù chöùc naêng theâm phaàn töû môùi vaøo danh saùch sao cho chuùng coù 
thöù töï taêng daàn. 
- vaø int retrieved() coù chöùc naêng hieån thò caùc phaàn töû trong danh saùch. 
 
2. Haõy vieát moät chöông trình coù aùp duïng tính ña hình. 
 
 
 
 
 
 
 
 
 
 
 
Baøi taäp chöông 9 

background image

Chöông 9      Tính ña hình 

                                                                                                           

 

295 

 

 
1. Xeùt ñoaïn chöông trình sau ñaây. Tìm loãi vaø giaûi thích taïi sao ? 
 
class base { 
public: 
  virtual int f(int a) = 0; 
  // ... 
}; 
 
class derived : public base { 
public: 
  int f(int a, int b) { return a*b; } 
  // ... 
}; 
 
2. Trình baøy söï khaùc nhau giöõa haøm aûo vaø quaù taûi haøm. 
 
3. Vieát chöông trình boå sung vaøo ví duï 4.1 chöông 9, baèng caùch quaù taûi hai toaùn töû + 
vaø toaùn töû -- vaøo lôùp daãn xuaát stack vaø queue .  
Toaùn töû + theâm moät phaàn töû vaøo danh saùch    
 

stack operator + (int  i) ; 

 

queue operator + (int  i) ; 

vaø toaùn töû -- laáy moät phaàn töû ra khoûi danh saùch. 
 

int  operator -- (int  unused) ; 

 // cho caû stack vaø queue .   

 
4. Haõy söûa ñoåi moät soá ví duï veà quaù taûi haøm trong caùc chöông tröôùc, sao cho coù theå 
chuyeån ñoåi caùc haøm ñöôïc quaù taûi thaønh caùc haøm aûo ? 
 
 
 
 
 
 
 
 
 
 

background image

 

 

 
Chöông 10   
 
 

Template vaø ñieàu khieån ngoaïi leä  

 
 
 
 
 
 
 
 

• 

Haøm template 

 

• 

Lôùp template 

 

• 

Ñieàu khieån ngoaïi leä 

 

• 

Bieán tónh 

 

• 

 Töø khoaù extern vaø asm 

 

• 

Haøm chuyeån kieåu 

 

• 

Nhöõng khaùc bieät giöõa C vaø C++ 

 
 
 
 

 
 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

298 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

299 

I/ Haøm template 

Haøm template (haøm maãu)  ñònh nghiaõ moät daõy toång quaùt caùc taùc vuï ñöôïc duøng cho 
nhieàu kieåu döõ lieäu khaùc nhau

. Trong ñoù, kieåu döõ lieäu ñöôïc duøng seõ ñöôïc truyeàn ñeán 

haøm döôùi daïng moät tham soá

.  

 
Vôùi cô cheá naøy, moät thuû tuïc coù theå ñöôïc duøng cho nhieàu kieåu döõ lieäu khaùc nhau
Trong moân hoïc Caáu truùc döõ lieäu vaø thuaät toaùn, nhieàu giaûi thuaät gioáng nhau veà maët 
luaän lyù, baát keå noù laøm vieäc vôùi kieåu döõ lieäu gì. Ví duï giaûi thuaät QuickSort laø gioáng 
nhau, khoâng caàn bieát noù seõ aùp duïng cho daõy soá nguyeân hay daõy soá thöïc. Vaán ñeà laø ôû 
choã döõ lieäu ñöôïc xöû lyù khaùc nhau. 
 
Baèng caùch taïo ra haøm template, coù theå ñònh nghiaõ baûn chaát cuûa giaûi thuaät ñoäc laäp vôùi 
kieåu döõ lieäu maø noù xöû lyù. Döïa vaøo haøm template, trình bieân dòch seõ töï ñoäng sinh ra 
maõ chöông trình ñeå duøng cho moät kieåu döõ lieäu cuï theå naøo ñoù khi thöïc thi chöông 
trình. Thöïc chaát laø vieäc taïo ra moät haøm template ñoàng nghiaõ vôùi vieäc taïo ra moät haøm 
maø noù coù theå töï quaù taûi leân chính noù

 
Khai baùo haøm template 
 
 

template  < class

  Ttype >   ret_type  func_name(parameter list)  

 { 
 

 

// body of function 

 
Töø khoaù template  duøng ñeå taïo ra moät daïng maãu moâ taû hoaït ñoäng cuûa haøm vaø 
nhöôøng cho trình bieân dòch ñieàn vaøo moät caùch chi tieát khi caàn. 
 
Ttype

 laø teân hình thöùc cho kieåu döõ lieäu ñöôïc duøng beân trong haøm, noù seõ ñöôïc thay 

theá bôûi moät kieåu döõ lieäu cuï theå khi trình bieân dòch sinh ra moät phieân baûn chi tieát cuûa 
haøm. 
 
Quaù trình taïo ra phieân baûn chi tieát cuûa haøm ñöôïc goïi laø quaù trình sinh haøm. Vieäc taïo 
ra  
baûn chi tieát cuûa haøm template ñöôïc goïi laø taïo ra ngay töùc khaéc (instantiating) moät 
haøm. Noùi moät caùch khaùc laø moät haøm sinh ra phieân baûn duøng trong choác laùt cuûa haøm 
template

 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

300 

Ví duï 1.1 

Haøm template trao ñoåi noäi dung cuûa hai bieán 

 
// Function template example. 
#include <iostream.h> 
// This is a function template. 
template

 <class X> void swapargs(X &a, X &b) 


  X temp; 
 
  temp = a; 
  a = b; 
  b = temp; 

 
int main() 

  int i=10, j=20; 
  float x=10.1, y=23.3; 
 
  cout << "Original i, j: " << i << ' ' << j << endl; 
  cout << "Original x, y: " << x << ' ' << y << endl; 
 
  swapargs(i, j);  

// swap integers 

  swapargs(x, y);   // swap floats 
 
  cout << "Swapped i, j: " << i << ' ' << j << endl; 
  cout << "Swapped x, y: " << x << ' ' << y << endl; 
 
  return 0; 

 
template

 <class X>  void swapargs(X &a, X &b) 

Doøng naøy thoâng baùo vôùi chöông trình hai vaán ñeà : 
- Ñaây laø moät haøm template. 
- Ñaây laø ñieåm baét ñaàu cuûa phaàn ñònh nghiaõ moät haøm template. 
 
X coù yù nghiaõ laø kieåu döõ lieäu cuûa caùc bieán caàn trao ñoåi noäi dung. 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

301 

Haøm swapargs() ñöôïc goïi hai laàn trong haøm main() : moät laàn ñeå trao ñoåi noäi dung 
hai bieán kieåu soá nguyeân, vaø laàn sau cho hai bieán kieåu soá thöïc. Do haøm swapargs() laø 
moät haøm template, cho neân trình bieân dòch seõ töï ñoäng phaùt sinh ra hai phieân baûn cuûa 
haøm swapargs() töông öùng vôùi kieåu döõ lieäu cuûa ñoái soá thöïc gôûi vaøo.  
 

• 

Phaàn khai baùo template cuûa moät haøm maãu khoâng baét buoäc phaûi vieát treân cuøng 

moät doøng vôùi teân haøm. 

 
Ví duï 1.2    
 
template 

<class X>  

void swapargs(X &a, X &b) 

  X  temp; 
 
  temp = a; 
  a = b; 
  b = temp; 

 
 

• 

Chuù yù raèng, khoâng theå ñaët baát kyø meänh ñeà naøo giöõa phaàn khai baùo template vaø 

phaàn thaân haøm. 

 
Ví duï 1.3    
 
// This will not compile. 
template <class X> 
int i

;    

 

 

 

// this is an error 

void swapargs(X &a, X &b) 

  X temp; 
 
  temp = a; 
  a = b; 
  b = temp; 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

302 

• 

Trong haøm template, coù theå söû duïng nhieàu kieåu döõ lieäu khaùc nhau baèng caùch 

ñöa vaøo moät danh saùch caùc kieåu döõ lieäu duøng trong haøm, trong ñoù teân hình thöùc 
cuûa caùc kieåu ñöôïc phaân caùch nhau baèng daáu phaåy. 

 
#include <iostream.h> 
template  

<class  type1, class  type2

void  myfunc(type1  x, type2  y) 

  cout << x << ' ' << y << endl; 

 
int main() 

  myfunc(10, "hi"); 
 
  myfunc(0.23, 10L); 
 
  return 0; 

 
@ Khi phaùt sinh haøm, caùc kieåu hình thöùc type1 vaø type2 ñöôïc thay theá hai laàn : laàn 
ñaàu baèng hai kieåu int vaø char*, laàn sau laø double vaø long . 
 
 

• 

Haøm template töông töï nhö haøm ñöôïc quaù taûi nhöng noù chòu nhieàu haïn cheá hôn. 

Khi quaù taûi moät haøm, caùc phieân baûn coù theå mang nhieàu taùc vuï raát khaùc nhau, 
trong khi moät haøm template chæ thöïc hieän ñöôïc moät coâng vieäc duy nhaát ôû taát caû 
caùc phieân baûn

 
Ví duï khoâng theå thay theá haøm ñöôïc quaù taûi sau ñaây baèng moät haøm template bôûi vì 
caùc haøm quaù taûi sau ñaây khoâng cuøng thöïc thi moät coâng vieäc. 
 
void outdata(int i) 

  cout << i; 

 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

303 

void outdata(double d) 

  cout << setprecision(10) << setfill('#'); 
  cout << d; 
  cout << setprecision(6) << setfill(' '); 

 

• 

Moät haøm template coù theå töï quaù taûi khi caàn thieát, khi ñoù caàn quaù taûi noù moät caùch 

töôøng minh. Neáu quaù taûi moät haøm template thì haøm ñöôïc quaù taûi seõ che haøm 
template ñoù

 
// Overriding a template function. 
#include <iostream.h> 
 
template <class X> void swapargs(X &a, X &b) 

  X temp; 
 
  temp = a; 
  a = b; 
  b = temp; 

 
// This overrides the generic version of swapargs(). 
void swapargs(int a, int b) 

  cout << "this is inside swapargs(int,int)\n"; 

 
int main() 

  int i=10, j=20; 
  float x=10.1, y=23.3; 
   
  cout << "Original i, j: " << i << ' ' << j << endl; 
  cout << "Original x, y: " << x << ' ' << y << endl; 
 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

304 

  swapargs(i, j);   // this calls the explicitly overloaded swapargs() 
  swapargs(x, y);   // swap floats 
 
  cout << "Swapped i, j: " << i << ' ' << j << endl; 
  cout << "Swapped x, y: " << x << ' ' << y << endl; 
 
  return 0; 

 
@ Vieäc quaù taûi leân moät haøm template, cho pheùp laäp trình vieân thay ñoåi giaûi thuaät  
cuûa moät phieân baûn cuûa haøm template ñeå phuø hôïp vôùi moät tình huoáng ñaëc bieät

. Tuy 

nhieân, neáu muoán söû duïng nhöõng phieân baûn hoaøn toaøn khaùc nhau cuûa moät haøm trong 
ñoù coù nhieàu kieåu döõ lieäu, haõy duøng quaù taûi haøm thay vì haøm template. 
 
 
Baøi taäp I 
 
1. Vieát moät chöông trình, trong ñoù coù haøm template teân laø min(),  traû noù veà giaù trò ñoái 
soá nhoû hôn trong hai giaù trò ñoái soá cuûa haøm.  Laáy ví duï min(3,4) = 3, hoaëc min('c', 'a') 
= 'a' . 
 
2. Vieát moät chöông trình, trong ñoù coù haøm template teân laø bubblesort(), thöïc hieän 
vieäc saép xeáp caùc döõ lieäu kieåu soá nguyeân, soá thöïc hoaëc kieåu kyù töï . Neáu thaønh coâng, 
haøm traû veà giaù trò 1, ngöôïc laïi haøm seõ traû veà trò laø -1. Haøm coù daïng 
 
 

int bubblesort (X a[], int  n);  

vôùi n xaùc ñònh soá löôïng caùc phaàn töû cuûa daõy a. 
 
3. Vieát moät chöông trình, trong ñoù coù haøm template teân laø find(),  thöïc hieän vieäc tìm 
kieám moät ñoái töôïng treân moät daõy. Neáu tìm thaáy, haøm traû veà chæ soá cuûa ñoái töôïng tìm 
ñöôïc, ngöôïc laïi haøm seõ traû veà trò laø -1. Haøm coù daïng 
 
 

int  find(int object, int *list,  int size);  

vôùi size xaùc ñònh soá löôïng caùc phaàn töû cuûa daõy. 
 
 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

305 

II/ Lôùp template 

 
Lôùp template

 ñònh nghiaõ taát caû caùc thuaät toaùn ñöôïc duøng bôûi lôùp ñoù, tuy nhieân kieåu 

döõ lieäu thöïc söï maø lôùp naøy xöû lyù seõ ñöôïc ñònh roõ döôùi daïng tham soá luùc taïo ra caùc ñoái 
töôïng thuoäc lôùp template ñoù. 
 

• 

Khai baùo 

 

template

  < class  Ttype >  class  class_name { 

 

 

// body of class 

}; 

 
Ttype

 laø teân lôùp hình thöùc vaø noù seõ ñöôïc xaùc ñònh khi taïo ra moät lôùp. Khi caàn thieát, 

coù theå ñònh nghiaõ lôùp template vôùi nhieàu kieåu döõ lieäu template baèng caùch duøng moät 
danh saùch caùc teân kieåu hình thöùc ñöôïc phaân caùch nhau baèng daáu phaåy. 
 

• 

Sau khi taïo ra lôùp template, coù theå sinh ra moät lôùp cuï theå töø lôùp template  

 
 

class_name  <

 type >  object_name

 
vôùi type laø teân thöïc cuûa kieåu döõ lieäu maø lôùp ñoù xöû lyù. 
 
Caùc  haøm thaønh phaàn cuûa moät lôùp template cuõng laø caùc haøm template moät caùch töï 
ñoäng

 vaø khoâng caàn phaûi duøng töø khoaù template ñeå khai baùo töôøng minh cho caùc haøm 

ñoù.  
 
 
Ví duï 2.1

 

Taïo ra lôùp template cho moät danh saùch lieân keát, duøng ñeå löu caùc kyù töï. 

// A simple generic linked list. 
#include <iostream.h> 
 
template < class  data_t

 >  class list { 

  data_t  data; 
  list *next; 
public: 
  list(data_t  d) ; 
  void add(list  *node) { 

node->next = this;  

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

306 

next = 0;  

  } 
  list *getnext() { return  next; } 
  data_t  getdata() { return  data; } 
}; 
 
template <

 class  data_t > list < data_t > :: list(data_t  d) 


  data = d; 
  next = 0; 

 
int main() 

  list<char>  start('a') 

;  

  list<char> *p, *last ; 
  int i; 
   
  // build a list 
  last = &start; 
  for(i=1; i<26; i++) { 
    p = new list<char> ('a' + i)
    p->add(last); 
    last = p; 
  } 
 
  // follow the list 
  p = &start; 
  while(p) { 
    cout << p->getdata(); 
    p = p->getnext(); 
  } 
 
  return 0; 

 
 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

307 

@ Löu yù doøng leänh  

list<char>  start('a') ;  

vôùi kieåu döõ lieäu ñöôïc truyeàn sang cho lôùp xuaát hieän beân trong caëp daáu  
ngoaëc 

< >. 

 
Keát quaû chöông trình ? 
 
@ Coù theå duøng danh saùch list ñeå löu tröõ caùc phaàn töû kieåu soá nguyeân hay khoâng ? 
 

• 

Coù theå söû duïng lôùp template list ôû treân cho moät kieåu döõ lieäu môùi do ngöôøi duøng 

ñònh nghiaõ. Ví duï, veà moät caáu truùc löu thoâng tin veà danh baï ñieän thoaïi 

 
struct  addr { 
  char name[40]; 
  char street[40]; 
  char city[30]; 
  char state[3]; 
  char phone[40]; 
  char zip[12]; 
}; 
 
Duøng lôùp template list ñeå sinh ra moät ñoái töôïng môùi obj  laø moät danh saùch lieân keát 
cuûa caùc phaàn töû thuoäc kieåu addr baèng khai baùo nhö sau  

list<addr>

  obj(structvar); 

 
vôùi structvar laø bieán coù kieåu döõ lieäu laø addr
 

• 

Caùc haøm template vaø lôùp template laø moät coâng cuï maïnh laøm gia taêng hieäu quaû 

laäp trình, bôûi vì noù cho pheùp ñònh nghiaõ moät giaûi thuaät ôû daïng toång quaùt vaø söû 
duïng ñöôïc cho nhieàu loaïi döõ lieäu coù kieåu khaùc nhau

. Ngoaøi ra, coøn tieát kieäm ñöôïc 

thôøi gian goõ chöông trình vaøo maùy tính

, do khoâng phaûi goõ laïi nhieàu ñoaïn maõ 

chöông trình gioáng nhau veà maët giaûi thuaät nhöng khaùc nhau veà kieåu döõ lieäu maø 
noù xöû lyù. 

 
Ví duï 2.2

 

Taïo ra lôùp template cho stack, duøng ñeå löu caùc kieåu döõ lieäu kyù töï vaø 
kieåu double. 

// This function demonstrates a generic stack. 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

308 

#include <iostream.h> 
#define SIZE 10 
 
// Create a generic stack class 
template <class StackType

 > class stack {  

  StackType  stck[SIZE];    

 

// holds the stack 

  int tos;  

 

 

 

 

// index of top-of-stack 

 
public: 
  void init() { tos = 0; }    

 

// initialize stack 

  void push(StackType  ch);  

 

 

// push object on stack 

  StackType pop();    

 

 

// pop object from stack 

}; 
 
// Push an object. 
template

 <class  StackType>  void stack<StackType>::push(StackType ob)  

{  
  if(tos==SIZE) { 
    cout << "Stack is full.\n"; 
    return; 
  } 
  stck[tos] = ob; 
  tos++; 

 
// Pop an object. 
template 

<class StackTypeStackType stack<StackType>::pop() 


  if(tos==0) { 
    cout << "Stack is empty.\n"; 
    return 0;    

 

 

// return null on empty stack  

  } 
  tos--; 
  return stck[tos]; 

 
 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

309 

int main() 

  // Demonstrate character stacks. 
  stack<char>  s1, s2;   

 

 

// create two stacks 

  int i; 
  
  // initialize the stacks 
  s1.init(); 
  s2.init(); 
 
  s1.push('a'); 
  s2.push('x'); 
  s1.push('b'); 
  s2.push('y'); 
  s1.push('c'); 
  s2.push('z'); 
 
  for(i=0; i<3; i++)   cout << "Pop s1: " << s1.pop() << "\n"; 
  for(i=0; i<3; i++)   cout << "Pop s2: " << s2.pop() << "\n"; 
 
  // demonstrate double stacks 
  stack<double>  ds1, ds2;   

 

// create two stacks 

 
 
  // initialize the stacks 
  ds1.init(); 
  ds2.init(); 
 
  ds1.push(1.1); 
  ds2.push(2.2); 
  ds1.push(3.3); 
  ds2.push(4.4); 
  ds1.push(5.5); 
  ds2.push(6.6); 
 
  for(i=0; i<3; i++) cout << "Pop ds1: " << ds1.pop() << "\n"; 
  for(i=0; i<3; i++) cout << "Pop ds2: " << ds2.pop() << "\n"; 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

310 

  return 0; 

 
Keát quaû chöông trình ? 
 
 

• 

Moät lôùp template coù theå chöùa nhieàu kieåu döõ lieäu toång quaùt (

generic data types.  

Khi ñoù caùc teân kieåu döõ lieäu template ñöôïc khai baùo trong phaàn template döôùi 
daïng moät danh saùch vaø phaân caùch nhau baèng daáu phaåy. 

 
Ví duï 2.3

 

Moät lôùp coù hai kieåu döõ lieäu toång quaùt 

 
// This example uses two generic data types in a class definition. 
#include <iostream.h> 
 
template <class 
Type1

class Type2>  class myclass 


  Type1  i; 
  Type2  j; 
public: 
  myclass(Type1 a, Type2 b) { i = a; j = b; } 
  void show() { cout << i << ' ' << j << '\n'; } 
}; 
 
int  main() 

  myclass<int, double>  ob1(10, 0.23);   

 

 

//   a/ 

  myclass<char, char *>  ob2('X', "This is a test");   

//   b/ 

 
  ob1.show();  

 

// show int, double 

  ob2.show();  

 

// show char, char * 

  
  return 0; 

 
Keát quaû chöông trình ? 
 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

311 

@ Trong caû hai tröôøng hôïp ôû treân (a/, b/) , trình bieân dòch seõ töï ñoäng sinh ra caùc döõ 
lieäu vaø haøm töông öùng vôùi meänh ñeà taïo ra lôùp. 
 
 
Baøi taäp II 
 
1. Vieát chöông trình taïo vaø bieåu dieãn moät lôùp template löu tröõ queue. 
 
2. Vieát chöông trình taïo moät lôùp template vôùi teân input, khi haøm taïo cuûa lôùp naøy 
ñöôïc goïi noù seõ thöïc hieän caùc coâng vieäc sau :   
 

-  thoâng baùo nhaéc ngöôøi duøng nhaäp döõ lieäu  : prompt message 

 

-  nhaän döõ lieäu töø baøn phím. 

 

- thoâng baùo loãi neáu döõ lieäu khoâng naèm trong vuøng trò cho pheùp  
giöõa min_value vaø max_value. 

 
Ñoái töôïng thuoäc kieåu input ñöôïc khai baùo nhö sau 
 

input  ob("prompt message", min_value, max_value) ; 

 

 
 

III/ Ñieàu khieån ngoaïi leä (exception handling) 

 
C++ (theo chuaån ANSI C++, 1994) cung caáp saün moät cô cheá xöû lyù loãi goïi laø ñieàu 
khieån ngoaïi leä. Qua ñoù coù theå khoáng cheá vaø ñaùp öùng laïi caùc loãi xuaát hieän luùc thöïc thi 
chöông trình

.   

 
1/ Ñieàu khieån ngoaïi leä cuûa C++ goàm ba töø khoaù : trycatchthrow .  
 
Moät caùch toång quaùt, caùc meänh ñeà duøng ñeå giaùm saùt caùc ngoaïi leä ñöôïc ñaët beân trong 
moät khoái try.  Khi moät ngoaïi leä (töùc moät loãi) xuaát hieän beân trong khoái try, noù seõ ñöôïc 
neùm ra (baèng töø khoaù throw). Tieáp theo ngoaïi leä naøy seõ bò baét laïi ñeå xöû lyù (baèng töø 
khoaù catch). 

 

 
Baát kyø moät meänh ñeà naøo thöïc hieän vieäc neùm ra ngoaøi moät ngoaïi leä phaûi ñaët ôû beân 
trong khoái try (hoaëc beân trong moät haøm ñöôïc goïi ñeán töø moät meänh ñeà beân trong khoái 
try). Taát caû caùc ngoaïi leä phaûi bò baét laïi bôûi moät meänh ñeà catch ñaët ngay sau khoái try 
maø töø ñoù noù ñöôïc neùm ra

 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

312 

Daïng khai baùo toång quaùt 

 
try 

{  

 

//  try block 

 

throw  exception

 ; 


catch 

(type1  arg ) {  

 

// catch  block 


catch 

(type2  arg ) {  

 

// catch  block 

 ... 

catch 

(typeN  arg ) {  

 

// catch  block 

 
exception

  laø giaù trò ñöôïc neùm ra. 

type1,  type2, ...,  typeN

  kieåu döõ lieäu cuûa caùc ñoái soá  

 
Kieåu döõ lieäu cuûa ngoaïi leä chính laø cô sôû ñeå quyeát ñònh xem ngoaïi leä ñoù ñöôïc xöû lyù 
baèng meänh ñeà catch naøo

. Nghiaõ laø neáu kieåu döõ lieäu xaùc ñònh trong moät catch naøo ñoù 

truøng hôïp vôùi kieåu döõ lieäu cuûa ngoaïi leä, thì meänh ñeà catch ñoù ñöôïc thöïc thi. Taát caû 
caùc meänh ñeà catch khaùc seõ bò boû qua.   
 
Khi moät ngoaïi leä bò baét laïi, arg seõ nhaän giaù trò cuûa ngoaïi leä naøy. Giaù trò ngoaïi leä coù 
theå laø moät kieåu döõ lieäu baát kyø,  keå caû kieåu döõ lieäu môùi do ngöôøi duøng taïo ra

 
 
Ví duï 3.1

 

Caùch ñieàu khieån ngoaïi leä cuûa C++ 

 
// A simple exception handling example. 
#include <iostream.h> 
 
int main() 

  cout << "start\n"; 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

313 

  try {  

 

 

 

 

// start a try block 

    cout << "Inside try block\n"; 
    throw 10

 

    // 

throw 

an 

error 

    cout << "This will not execute"; 

// not  execution 

  } 
 
  catch (int i) {  

 

 

 

// catch an error 

    cout << "Caught One! Number is: "; 
    cout << i << "\n"; 
  } 
 
  cout << "end"; 
  return 0; 

 
Giaûi thích keát quaû chöông trình  ? 
start 
Inside try block 
Caught One ! Numbers is  : 10 
end 
 
@ Khi moät ngoaïi leä ñöôïc neùm ra, ñieàu khieån cuûa chöông trình seõ chuyeån ñeán bieåu 
thöùc cuûa catch vaø keát thuùc vieäc thöïc thi khoái try

 
Ngay sau khoái catch laø moät leänh goïi ñeán haøm exit(), hay abort(), v.v... vì phaàn ñieàu 
khieån ngoaïi leä thöôøng ñöôïc duøng ñeå xöû lyù caùc loãi raát nghieâm troïng. 
 

• 

Kieåu cuûa ngoaïi leä phaûi gioáng vôùi kieåu xaùc ñònh trong meänh ñeà catch

 

Ví duï 3.2

  Moät chöông trình keát thuùc khoâng bình thöôøng do meänh ñeà catch seõ 

khoâng baét ñöôïc ngoaïi leä neùm ra. 

 
// This example will not work. 
#include <iostream.h> 
 
int main() 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

314 

  cout << "start\n"; 
 
  try 

{  

 

 

 

 

// start a try block 

    cout << "Inside try block\n"; 
    throw 10

 

    // 

throw 

an 

error 

    cout << "This will not execute"; 
  } 
 
  catch (double i) {   

 

 

// Won't work for an int exception 

    cout << "Caught One! Number is: "; 
    cout << i << "\n"; 
  } 
 
  cout << "end"; 
  return 0; 

 
Giaûi thích keát quaû chöông trình ? 
start 
inside try block 
 
Abnormal program terminal

 

 

 

(Daïng thoâng baùo loãi naøy coù theå khaùc nhau tuyø thuoäc vaøo moãi compiler) 
 
 

• 

Moät ngoaïi leä coù theå ñöôïc neùm ra töø moät  meänh ñeà naèm ngoaøi khoái try chæ khi noù 

ñöôïc ñaët trong moät haøm, maø haøm naøy ñöôïc goïi töø trong khoái try

 

Ví duï 3.3

  Moät chöông trình keát thuùc bình thöôøng.  

// Throwing an exception from a function outside  the try block.  
#include <iostream.h> 
void Xtest(int test) 

  cout << "Inside Xtest, test is: " << test << "\n"; 
  if(test)  

throw 

test; 


 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

315 

int main() 

  cout << "start\n"; 
 
  try {  

 

 

 

 

// start a try block 

    cout << "Inside try block\n"; 
    Xtest(0); 
    Xtest(1); 
    Xtest(2); 
  } 
  catch (int i) {  

 

 

 

// catch an error 

    cout << "Caught One! Number is: "; 
    cout << i << "\n"; 
  } 
 
  cout << "end"; 
  return 0; 

 
Giaûi thích keát quaû chöông trình  
start 
Inside try block 
Inside Xtest, test is: 0 
Inside Xtest, test is: 1 
Caught One! Number is: 1 
end 
 

• 

Moät khoái try coù theå thuoäc veà moät haøm khaùc haøm main() cuûa chöông trình

. Trong 

tröôøng hôïp naøy, cöù moãi laàn thöïc hieän haøm, boä ñieàu khieån ngoaïi leä cuûa haøm ñoù seõ 
ñöôïc laëp laïi. 

 

Ví duï 3.4

  Moät khoái try/catch coù theå ôû beân trong moät haøm khaùc haøm main().  

#include <iostream.h> 
// A try/catch can be inside a function other than main(). 
void Xhandler(int test) 

  try

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

316 

    if(test)   throw test; 
  } 
  catch(int i) { 
    cout << "Caught One!  Ex. #: " << i << '\n'; 
  } 

 
int main() 

  cout << "start\n"; 
 
  Xhandler(1); 
  Xhandler(2); 
  Xhandler(0); 

// not throw 

  Xhandler(3); 
 
  cout << "end"; 
 
  return 0; 

 
@ Coù 3 ngoaïi leä ñöôïc neùm ra. Sau moãi ngoaïi leä, khi haøm ñöôïc goïi laàn nöõa thì boä xöû 
lyù loãi ñöôïc laäp laïi. 
 

• 

Coù theå taïo nhieàu meänh ñeà catch cho moãi khoái try. Do moãi meänh ñeà catch coù theå 

baét moät kieåu ngoaïi leä khaùc bieät vôùi kieåu ôû caùc catch khaùc. 

 

Ví duï 3.5

  Moãi bieåu thöùc catch ñöôïc kieåm tra theo thöù töï xuaát hieän vaø chæ coù moät 

meänh ñeà truøng kieåu môùi ñöôïc thöïc thi. Taát caû caùc meänh ñeà coøn laïi ñeàu bò boû qua. 

#include <iostream.h> 
 
// Different types of exceptions can be caught. 
void Xhandler(int test) 

  try

    if(test)   throw  test; 
    else  

throw

  "Value is zero"; 

Giaûi thích keát quaû chöông trình ? 
 
start 
Caught One! Ex. #: 1 
Caught One! Ex. #: 2 
Caught One! Ex. #: 3 
end 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

317 

  } 
  catch(int i) { 
    cout << "Caught One!  Ex. #: " << i << '\n'; 
  } 
  catch(char *str) { 
    cout << "Caught a string: "; 
    cout << str << '\n'; 
  } 

 
int main() 

  cout << "start\n"; 
  Xhandler(1); 
  Xhandler(2); 
  Xhandler(0); 
  Xhandler(3); 
  cout << "end"; 
  return 0; 

 
 
2/

 Trong moät soá tröôøng hôïp, seõ caàn moät boä ñieàu khieån ngoaïi leä coù theå baét ñöôïc taát caû 

caùc kieåu cuûa ngoaïi leä thay vì moät kieåu naøo ñoù

. Söû duïng meänh ñeà catch theo daïng sau  

 

catch

(...) { 

  // process all exceptions 

 

Daáu "..." baét ñöôïc taát caû kieåu 

 

• 

Khi moät haøm ñöôïc goïi töø beân trong  khoái block, coù theå haïn cheá kieåu döõ lieäu naøo 

cuûa ngoaïi leä maø haøm coù theå neùm ñöôïc. Ñeå thöïc hieän caùc haïn cheá, caàn phaûi 
throw vaøo ñònh nghiaõ haøm. Daïng toång quaùt 

 

ret_type  

func_name(arg_list)  throw(type_list) { 

  // 

..... 

Giaûi thích keát quaû chöông trình ? 
 
start 
Caught One! Ex. #: 1 
Caught One! Ex. #: 2 
Caught a string: Value is zero 
Caught One! Ex. #: 3 
end 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

318 

Chæ coù caùc ngoaïi leä coù kieåu trong danh saùch type_list (phaân caùch baèng daâuù phaåy) laø 
ñöôïc neùm ra töø haøm. Ngöôïc laïi, vieäc neùm ra caùc ngoaïi leä thuoäc kieåu khaùc laø chöông 
trình keát thuùc baát thöôøng. 
 
Löu yù 

Neáu ñang duøng trình bieân dòch tuaân theo chuaån ANSI C++, thì vieäc thöû neùm 
ra moät ngoaïi leä maø khoâng coù meänh ñeà catch naøo baét ñöôïc seõ laøm goïi haøm 
unexpected()

 . Theo maëc ñònh, haøm unexpected() seõ goïi tieáp haøm abort() ñeå 

laøm keát thuùc chöông trình moät caùch baát thöôøng. 

 
Cuõng coù theå ñònh laïi ñeå haøm unexpected() goïi ñeán moät haøm xöû lyù keát thuùc khaùc neáu 
laäp trình vieân muoán. Xem chi tieát taøi lieäu höôùng daãn di keøm trong trình bieân dòch. 
 

• 

Neáu muoán neùm moät laàn nöõa moät ngoaïi leä töø beân trong boä ñeàu khieån ngoaïi leä, 

haõy goïi moät laàn nöõa töø khoaù throw khoâng caàn keøm theo giaù trò cuûa ngoaïi leä. 
Caùch naøy cho pheùp ngoaïi leä hieän haønh ñöôïc truyeàn ñeán moät ñoaïn try/catch khaùc. 

 
Ví duï 3.6 

 Duøng catch(...) ñeå baét moïi ngoaïi leä 

// This example catches all exceptions. 
#include <iostream.h> 
 
void Xhandler(int test) 

  try
    if(test==0)  

throw 

test;    

// throw int 

    if(test==1)  

throw 

'a';    

// throw char 

    if(test==2)  

throw 

123.23;  

// throw double 

  } 
  catch(...) {   

 

 

// catch all exceptions 

    cout << "Caught One!\n"; 
  } 

 
 
 
int main() 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

319 

  cout << "start\n"; 
 
  Xhandler(0); 
  Xhandler(1); 
  Xhandler(2); 
 
  cout << "end"; 
  return 0; 

 
 
 

• 

Boä ñieàu khieån ngoaïi leä catch(...) coù khaû naêng baét ñöôïc ngoaïi leä thuoäc baát kyø kieåu 

naøo

, baèng caùch ñöa catch(...) vaøo cuoái caùc boä ñieàu khieån ngoaïi leä catch khaùc 

trong chöông trình. 

 
Ví duï 3.7 
// This example uses catch(...) as a default. 
#include <iostream.h> 
 
void Xhandler(int test) 

  try
    if(test==0)  

throw 

test;    

// throw int 

    if(test==1)  

throw 

'a';    

// throw char 

    if(test==2)  

throw 

123.23;  

// throw double 

  } 
  catch(int i) {  

 

 

// catch an int exception 

    cout << "Caught " << i << '\n'; 
  } 
  catch(...) {   

 

 

// catch all other exceptions 

    cout << "Caught One!\n"; 
  } 

 
int main() 

Giaûi thích keát quaû chöông trình ? 
start 
Caught One!  
Caught One!  
Caught One!  
end 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

320 

  cout << "start\n"; 
 
  Xhandler(0); 
  Xhandler(1); 
  Xhandler(2); 
 
  cout << "end"; 
  return 0; 

 
Keát quaû chöông trình  
start 
Caught  0  
Caught One!  
Caught One!  
end 
 
@ Nhö vaäy catch(...) ñöôïc duøng ñeå taïo ra moät boä xöû lyù loãi maëc ñònh coù baét ñöôïc taát 
caû caùc ngoaïi leä, ngoaøi caùc ngoaïi leä maø laäp trình vieân ñaõ quan taâm vaø xöû lyù moät caùch 
töôøng minh. Hôn naøy, caùch duøng naøy giuùp ngaên ngöøa ñöôïc vieäc ngoaïi leä neùm ra maø 
khoâng coù boä xöû lyù naøo baét ñöôïc

, laøm daãn ñeán keát thuùc chöông trình moät caùch baát 

thöôøng . 
 

• 

Caùch haïn cheá caùc kieåu cuûa ngoaïi leä ñöôïc neùm ra töø trong moät haøm. 

 
Ví duï 3.8   

Haøm chæ bò haïn cheá kieåu ngoaïi leä ñöôïc neùm ra töø khoái try maø haøm ñöôïc 

goïi 
 
// Restricting function throw types. 
#include <iostream.h> 
 
// This function can only throw ints, chars, and doubles. 
void Xhandler(int test)  throw(int, char, double) 

  if(test==0)  throw test;    

// throw int 

  if(test==1)  throw 'a';    

// throw char 

  if(test==2)  throw 123.23;  

// throw double 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

321 


 
int main() 

  cout << "start\n"; 
  try
    Xhandler(0);  

 

// also, try passing 1 and 2 to Xhandler() 

  } 
  catch(int i) { 
    cout << "Caught int\n"; 
  } 
  catch(char c) {  
    cout << "Caught char\n"; 
  } 
  catch(double d) {  
    cout << "Caught double\n"; 
  } 
 
  cout << "end"; 
  return 0; 

 
@ Ñieàu gì xaûy ra khi khoâng coù doøng catch(int i) {cout << "Caught int\n"; } ? 
 
@ Noäi dung môùi cuûa haøm void Xhandler() giuùp noù ngaên ngöøa vieäc neùm baát kyø ngoaïi 
leä naøo . 
 
Ví duï 3.9

 

 
// This function can throw NO exceptions! 
void Xhandler(int test)  throw() 

  /* The following statements no longer work.  Instead, 
     They will cause an abnormal program termination. */ 
  if(test==0)  throw test;  
  if(test==1)  throw 'a';  
  if(test==2)  throw 123.23;  

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

322 


 

• 

Coù theå neùm ra moät laàn nöõa moät ngoaïi leä. Nguyeân nhaân thöôøng gaëp cuûa vieäc 

neùm laïi naøy laø cho pheùp boä xöû lyù truy caäp nhieàu laàn moät ngoaïi leä

 
Ví duï 3.10 

Chöông trình neùm ra moät ngoaïi leä kieåu char * 

 
// Example of "rethrowing" an exception. 
#include <iostream.h> 
 
void Xhandler() 

  try 
    throw "hello";    

 

 

 

// throw a char * 

  } 
 
  catch(char *) {    

 

 

 

// catch a char * 

    cout << "Caught char * inside Xhandler\n"; 
    throw ;    

 

 

 

 

// rethrow char * out of function 

  } 

 
int main() 

  cout << "start\n"; 
 
  try
    Xhandler(); 
  } 
  catch(char *) { 
    cout << "Caught char * inside main\n"; 
  } 
 
  cout << "end"; 
  return 0; } 
Baøi taäp III 
 

Giaûi thích keát quaû chöông trình ? 
 
start 
Caught char * inside Xhandler  
Caught char * inside main 
end 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

323 

1. Tìm ñieåm sai vaø söûa loãi trong chöông trình sau 
int main() 

  throw 12.23; 
    ...  } 
 
2. Tìm ñieåm sai vaø söûa loãi trong chöông trình sau 
try { 
  // ... 
  throw 'a'; 
  // ... 

catch(char *) { 
 // ... 

 
3. Ñieàu gì xaûy ra khi moät ngoaïi leä bò neùm ra maø khoâng coù meänh ñeà catch töông öùng 

 
4. Tìm ñieåm sai vaø söûa loãi trong chöông trình sau 
try { 
  // ... 
  throw 10; 

catch(int *p) { 
  // ... 

 
5. Haõy theâm vaøo haøm sau ñaây chöùc naêng kieåm tra loãi khi chia chi giaù trò zero. 
double divide(double a, double b) 

  // add error handling 
  return a/b; 

 

IV/ Bieán tónh 

 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

324 

1/ Khaùi nieäm 
Moät bieán phaàn töû cuûa lôùp coù theå ñöôïc khai baùo laø bieán tónh. Moät haøm thaønh phaàn cuûa 
lôùp cuõng coù theå ñöôïc khai baùo laø tónh, nhöng ít söû duïng (khoâng baøn ñeán trong baøi 
giaûng naøy).  
 
Söû duïng bieán tónh, coù theå traùnh ñöôïc moät soá vaán ñeà phöùc taïp. 
 
Khi khai baùo moät  bieán laø bieán tónh, coù nghóa laø cho pheùp moät  baûn duy nhaát cuûa bieán 
ñoù ñöôïc toàn taïi 

baát keå coù bao nhieâu ñoái töôïng thuoäc lôùp ñoù ñöôïc sinh ra. Taát caû caùc 

ñoái töôïng  ñoù söû duïng chung bieán tónh

. Ngoaøi ra, coøn cho taát caû caùc lôùp khaùc thöøa keá 

töø lôùp ñoù söû duïng bieán tónh. 
 
Moät bieán tónh toàn taïi ngay tröôùc khi lôùp cuûa noù ñöôïc taïo ra. Xeùt veà baûn chaát, bieán 
tónh laø moät bieán toaøn cuïc nhöng phaïm vi coù nghóa cuûa noù chæ giôùi haïn trong lôùp maø 
noù ñöôïc khai baùo. Do ñoù coù theå truy caäp moät bieán tónh ñoäc laäp vôùi baát kyø ñoái töôïng 
naøo. 
 
Nguyeân nhaân chính maø C++ hoå trôï caùc bieán tónh laø ñeà phoøng nhu caàu söû duïng bieán 
toaøn cuïc. Löu yù, vieäc söû duïng  caùc lôùp vaøo caùc bieán toaøn cuïc thöôøng xuyeân vi phaïm 
nguyeân taéc ñoùng goùi, moät nguyeân taéc caên baûn cuûa laäp trình höôùng ñoái töôïng . 
 
 
2/ Khai baùo, ñònh nghóa vaø khôûi taïo 
Bieán tónh ñöôïc khai baùo trong moät  lôùp. Phaàn ñònh nghóa bieán tónh laïi ôû beân ngoaøi 
lôùp. Do ñoù caàn söû duïng toaùn töû phaïm vi ñi keøm vôùi bieán tónh. 
 
Taát caû caùc bieán tónh ñeàu ñöôïc khôûi taïo baèng giaù trò zero theo maëc ñònh

. Maëc khaùc coù 

theå khôûi taïo baèng giaù trò khaùc. 
 
Ví duï 4.1 
// A static member variable example. 
#include <iostream.h> 
 
class myclass { 
  static int i; 
public: 
  void seti(int n) { i = n; } 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

325 

  int geti() { return i; } 
}; 
 
// Definition of myclass::i. i is still private to myclass. 
int myclass::i 
 
int main() 

  myclass o1, o2; 
 
  o1.seti(10);  
 
  cout << "o1.i: " << o1.geti() << '\n';   // displays 10 
  cout << "o2.i: " << o2.geti() << '\n';   // also displays 10  
 
  return 0; 

 
@ Veà maët kyõ thuaät, khai baùo moät  lôùp chæ laø moät  söï thoâng baùo. Vì bieán tónh haøm yù 
raèng  boä nhôù ñöôïc daønh cho bieán ñoù, phaàn ñònh nghóa bieán caàn thieát ñeå caát leân vuøng 
ñöôïc caáp

 

• 

Bieán tónh coù theå ñöôïc truy caäp moät  caùch ñoäc laäp vôùi ñoái töôïng  bôûi vì noù coù 
tröôùc caùc ñoái töôïng. 

 
Ví duï 4.2 
// Use a static member variable independent of any object. 
#include <iostream.h> 
 
class myclass { 
public: 
  static int i; 
  void seti(int n) { i = n; } 
  int geti() { return i; } 
}; 
int myclass::i
 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

326 

int main() 

  myclass o1, o2; 
 
  // set i directly 
  myclass::i = 100;    

// no object is referenced. 

 
  cout << "o1.i: " << o1.geti() << '\n';   // displays 100 
  cout << "o2.i: " << o2.geti() << '\n';   // also displays 100 
 
  return 0; 

 
@ Bieán tónh i ñöôïc gaùn gía trò 100 maø khoâng caàn tham khaûo ñeán moät  ñoái töôïng  cuï 
theå naøo. 
 

• 

Caùch söû duïng thoâng thöôøng cuûa bieán tónh laø ñònh vò truy caäp ñeán moät taøi 
nguyeân duøng chung 

nhö file, maùy in hay server. Vieäc ñònh vò naøy ñoøi hoûi moät 

soá phöông tieän ñeå saép haøng caùc bieán coá

 
Ví duï 4.3 

Chöông trình seõ taïo ra moät  lôùp output, duøng moät  bieán tónh kieåu maûng 

kyù töï laøm vuøng ñeäm xuaát vôùi teân laø outbuf. Vuøng ñeäm naøy ñöôïc duøng ñeå nhaän caùc 
keát xuaát sinh ra bôûi haøm thaønh phaàn putbuf(). Haøm putbuf() gôûi töøng kyù töï cuûa noäi 
dung bieán chuoåi str, cuï theå laø noù ñoøi quyeàn truy caäp ñeán vuøng ñeäm roài gôûi taát caû caùc 
kyù töï cuûa chuoåi str. Trong suoát thôøi gian keát xuaát, haøm putbuf() khoaù khoâng cho caùc 
ñoái töôïng khaùc truy caäp ñeán vuøng ñeäm. 
 
// A shared resource example. 
#include <iostream.h> 
#include <string.h> 
 
class output { 
  static char outbuf[255];   // this is the shared resource 
  static int inuse;    

// buffer available if 0; in use otherwise 

  static int oindex;    

// index of outbuf 

  char str[80]; 
  int i;   

 

 

// index of next char in str 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

327 

  int who;    

 

// identifies the object, must be > 0 

public: 
  output(int w, char *s) { strcpy(str, s); i = 0; who = w; } 
 
  /* This function returns -1 if waiting for buffer, 
     it returns 0 if it is done outputting, and 
     it returns who if it is still using the buffer.  */ 
  int putbuf()  

 

 

 

// from str[]  to  outbuf[] 

  { 
    if(!str[i]) {  

 

 

 

// done outputting 

      inuse = 0;  

 

 

 

// release buffer 

      return 0;   

 

 

// signal termination 

    } 
 
    if(!inuse)   inuse = who;  

 

// get buffer 

 
    if(inuse != who)   return -1;   // in use by someone else 
 
    if(str[i]) {   

 

 

// still chars to output 

      outbuf[oindex] = str[i]; 
      i++; oindex++; 
      outbuf[oindex] = '\0';     

// always keep null-terminated 

      return 1; 
    } 
    return 0; 
  } 
 
  void show() { cout << outbuf << '\n'; } 
}; 
 
char output::outbuf[255];  

 

// this is the shared resource 

int output::inuse = 0;  

 

// buffer available if 0; in use otherwise 

int output::oindex = 0;    

// index of outbuf 

 
 
int main() 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

328 

  output o1(1, "This is a test"),  o2(2, " of statics"); 
 
  while(o1.putbuf() | o2.putbuf()) ;  

 

// output chars 

 
  o1.show(); 
  return 0; 

 
Keát quaû chöông trình ? 
 
 
Baøi taäp IV 
 
1. Vieát laïi chöông trình trong ví duï 4.3 chöông 10, ñeå coù theå trình baøy teân cuûa ñoái 
töôïng  ñang truy caäp ñeán vuøng ñeäm vaø teân caùc ñoái töôïng ñang bò caám truy caäp vuøng 
ñeäm. 
 
2. Bieán tónh ñöôïc öùng duïng ñeå theo doõi soá löôïng caùc ñoái töôïng cuûa moät lôùp toàn taïi ôû 
moät  thôøi ñieåm baát kyø

. Baèng caùch seõ taêng trò soá ñeám cuûa moät  bieán tónh moãi luùc haøm 

taïo cuûa lôùp ñöôïc goïi, vaø laøm giaûm trò soá ñeám moãi khi haøm huûy cuûa lôùp ñöôïc goïi. 
Vieát chöông trình taïo moät lôùp test coù bieán tónh count laø bieán rieâng, moät haøm taïo, haøm 
huûy vaø haøm getcount() traû veà gía trò cuûa count. Chöông trình coù söû duïng 3 ñoái töôïng 
vaø moät con troû ñoái töôïng p. 
 
 

V/ Töø khoaù extern vaø asm 

 
C++ cung caáp hai cô cheá quan troïng laøm cho vieäc keát noái giöõa chöông trình C++ vaø 
chöông trình ngoân ngöõ khaùc trôû neân deã daøng hôn. 
 
Cô cheá 1 : boä chæ ñònh keát noái (extern)  duøng ñeå thoâng baùo vôùi trình bieân dòch raèng 
moät hay moät soá haøm naøo ñoù trong chöông trình seõ ñöôïc keát noái vôùi moät ngoân ngöõ 
khaùc, vaø chuùng coù theå coù nhöõng qui öôùc khaùc veà vieäc truyeàn tham soá. Daïng toång 
quaùt 
 
 

extern

 “Language” { 

function_prototypes 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

329 

 } 
 
Language

 : teân cuûa ngoân ngöõ maø haøm cuûa chöông trình caàn keát noái 

function_prototypes 

 : caùc haøm caàn keát noái 

 
Taát caû caùc chæ ñònh keát noái phaûi mang tính toaøn cuïc vaø noù khoâng theå naèm beân trong 
moät  haøm. Ngoaøi ra coù theå chæ ñònh keát noái cho caùc ñoái töôïng (ít xaûy ra).  
 
Ví duï

 5.1 Chöông trình sau keát noái haøm func() theo kieåu haøm cuûa C hôn laø haøm cuûa 

C++ 
 
// Illustrate linkage specifier. 
#include <iostream.h> 
 
extern 

"C"  int  func(int x);  

 

 

// link as C function 

 
// This function now links as a C function. 
int func(int x) 

  return x/3; 

 
 
Ví duï

 5.2   Ñoaïn chöông trình sau thoâng baùo vôùi trình bieân dòch raèng f1(), f2(), f3() 

seõ ñöôïc keát noái nhö caùc haøm cuûa C. 
 
extern 

"C" { 

  void f1(); 
  int  f2(int x); 
  double f3(double x, int *p); 

 
Cô cheá 2 : töø khoaù asm cho pheùp laäp trình vieân nhuùng ñoaïn maõ leänh hôïp ngöõ vaøo 
trong chöông trình nguoàn C++. 
 
Öu ñieåm : chöông trình öùng duïng hoaøn toaøn laø moät chöông trình C++ vaø noù khoâng 
caàn phaûi keát noái vôùi caùc file chöông trình hôïp ngöõ khaùc. Daïng toång quaùt 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

330 

 
 

asm

(“op_code”) ; 

 
op_code

 laø moät caâu leänh hôïp ngöõ nhuùng trong chöông trình. 

 
Löu yù Turbo C++ vaø Borland C++ chaáp nhaän moät soá daïng khaùc nhau cuûa meänh ñeà 
asm : 
 

asm

  op_code

 

asm

  op_code newline; 

 

asm

  { 

  // 

statements; 

 
 
Ví duï

 5.3   Ñoaïn chöông trình sau nhuùng nhieàu caâu leänh hôïp ngöõ vaøo haøm func() 

 
// Don't try this function! 
void func() 

  asm("mov bp, sp"); 
  asm("push ax"); 
  asm("mov cl, 4"); 
  // ... 

 
Baøi taäp V 
 
1. Nghieân cöùu taøi lieäu höôùng daãn söû duïng caùc trình bieân dòch sau ñaây, nhöõng noäi 
dung lieân quan ñeán chæ ñònh keát noái vaø giao tieáp vôùi asembly : 

- Borland C++ version 4.5 hoaëc cao hôn 
- Visual C++ version 6.0 hoaëc cao hôn 

 
 
 
 

VI/ Haøm chuyeån kieåu 

 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

331 

Vieäc chuyeån ñoåi moät  ñoái töôïng thuoäc kieåu naøy thaønh moät ñoái töôïng kieåu khaùc toû ra 
höõu ích trong moät  soá tröôøng hôïp. Coù theå söû duïng quaù taûi toaùn töû ñeå thöïc hieän vieäc 
chuyeån ñoåi, nhöng caùch söû duïng haøm chuyeån kieåu laø moät  giaûi phaùp deã daøng vaø hay 
hôn. 
 
Moät haøm chuyeån kieåu thöïc hieän töï ñoäng vieäc chuyeån ñoåi moät ñoái töôïng thaønh moät giaù 
trò töông thích vôùi kieåu cuûa bieåu thöùc maø ñoái töôïng ñoù coù tham gia

 
Daïng toång quaùt 
 
 

operator

  type()  { return  value; } 

 
type 

laø kieåu caàn chuyeån 

value

 laø gía trò cuûa ñoái töôïng sau khi ñöôïc chuyeån 

 
Haøm seõ traû veà gía trò thuoäc kieåu type.  
 
Haøm chuyeån kieåu khoâng coù tham soá vaø noù phaûi laø haøm thaønh phaàn cuûa lôùp trong ñoù 
haøm thöïc hieän vieäc chuyeån kieåu.  
 
 
Haøm chuyeån kieåu cung caáp moät caùch tieáp caän saùng suûa hôn cho vieäc chuyeån kieåu 
cuûa ñoái töôïng so vôùi caùc phöông phaùp cuûa C++, bôûi vì noù cho pheùp moät ñoái töôïng 
ñöôïc söû duïng tröïc tieáp trong bieåu thöùc thuoäc kieåu caàn chuyeån ñeán. 
 
 
Ví duï

 6.1 

Lôùp coord coù moät haøm chuyeån kieåu thaønh kieåu nguyeân.  
Haøm traû veà gía trò tích cuûa hai toaï ñoä 

 
// A simple conversion function example. 
#include <iostream.h> 
 
class coord { 
  int x, y; 
public: 
  coord(int i, int j) { x = i; y = j; } 
  operator int() { return x*y; }    

// conversion function 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

332 

}; 
 
 
int main() 

  coord o1(2, 3), o2(4, 3); 
  int i; 
 
  i = o1;   

 

// automatically convert to integer 

  cout << i << '\n'; 
 
  i = 100 + o2;   

// convert o2 to integer 

  cout << i << '\n'; 
 
  return 0; 

 
@ Baèng caùch duøng haøm chuyeån kieåu, caùc lôùp töï taïo ñöôïc hoaø nhaäp vaøo trong moät 
bieåu thöùc thoâng thöôøng cuûa C++ maø khoâng caàn phaûi söû duïng moät maûng caùc toaùn töû 
quùa taûi raát phöùc taïp. 
 
 
Ví duï

 6.2 

Lôùp strtype coù moät haøm chuyeån kieåu chuyeån chuoåi kyù töï thaønh  
moät con troû ñeán chuoåi str  

 
#include <iostream.h> 
#include <string.h> 
 
class strtype { 
  char str[80]; 
  int len; 
public: 
  strtype(char *s) { strcpy(str, s); len = strlen(s); } 
  operator char *() { return str; }  

 

 

// convert to char* 

}; 
int main() 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

333 

  strtype s("This is a test\n"); 
  char *p, s2[80]; 
 
  p = s;  

 

 

 

 

// convert to char * 

  cout << "Here is string: " << p << '\n'; 
 
  // convert to char * in function call 
  strcpy(s2, s); 
  cout << "Here is copy of string: " << s2 << '\n'; 
 
  return 0; 

 
@ Haøm chuyeån kieåu khoâng chæ ñöôïc goïi khi ñoái töôïng s bò gaùn cho con troû p, maø coøn 
ñöôïc goïi khi ñoái töôïng s ñöôïc duøng nhö moät tham soá cuûa haøm strcpy() coù daïng  
 

char *strcpy(char *s1, char *s2) ; 

 
Vì s2 coù kieåu char *, neân haøm chuyeån kieåu thaønh char * seõ ñöôïc goïi thöïc thi moät 
caùch töï ñoäng.  
 
@ Nhö vaäy haøm chuyeån kieåu coù theå giuùp laäp trình vieân tích hôïp caùc lôùp töï taïo vaøo 
thö vieän haøm chuaån cuûa C++ 

moät caùch eâm thaám. 

 
 
Baøi taäp VI 
 
1. Qua lôùp strtype trong ví duï 7.2 chöông 10, vieát chöông trình taïo ra moät haøm 
chuyeån sang kieåu nguyeân. Haøm seõ traû veà gía trò laø chieàu daøi cuûa chuoãi kyù töï str.   
 
2. Cho moät lôùp sau 
 

class pwr { 

  int 

base; 

  int 

exp; 

 public: 
 

 

pwr(int b, int e) {base = b; exp = e;} 

 

 

// create conversion to integer here 

}; 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

334 

 
Haõy taïo ra moät haøm chuyeån moät ñoái töôïng kieåu pwr thaønh kieåu nguyeân. Haøm seõ traû 
veà gía trò cuûa bieán base.   
 
 

VII/  Nhöõng khaùc bieät giöõa C vaø C++ 

 
C++ laø moät sieâu taäp hôïp cuûa C, vaãn coù moät soá khaùc bieät giöõa C vaø C++, söï khaùc bieät 
naøy coù theå laøm cho trình bieân dòch C++ khoâng bieân dòch ñöôïc moät soá chöông trình C 
naøo ñoù. Do ñoù laäp trình vieân caàn naém vöõng ñeå vieát moät chöông trình C++ ñöôïc toát. 
 
 
 

Caùc khaùc bieät 

C++ 

1/  Haøm khoâng coù ñoái soá   Nguyeân maãu cuûa haøm coù töø 

khoaù void 
Vd :        char f1(void); 

Töø khoaù void laø tuyø yù  
 
Vd :        char f1(); 

2/   Haèng kyù töï  

ñöôïc töï ñoäng chuyeån thaønh 
soá nguyeân 

Khoâng theå 

3/ Bieán toaøn cuïc khai 

baùo nhieàu laàn ôû nhieàu 
nôi 

Khoâng baùo loãi 

baùo loãi 

4/  Teân (identifier) toái ña  31 kyù töï  

1024 kyù töï  

5/   Goïi haøm main() 

Töø beân trong chöông trình 

Cho pheùp, khoâng neân 
laïm duïng 

 
 
 
 
 
 
 
 
 
 
 
Baøi taäp chöông 10 
 

background image

Chöông 10   Template vaø ñieàu khieån ngoaïi leä 

                                                               

 

 

 

335 

 
1.  Söï khaùc bieät giöõa caùc bieán tónh vaø caùc bieán khaùc cuûa moät lôùp laø gì ? 
 
2. Ngoaøi vieäc nhaäp/xuaát theo maûng söû duïng boä nhôù nhö moät thieát nhaäp/xuaát, coøn coù 
söï khaùc bieät naøo giöõa noù vaø nhaäp/xuaát thoâng thöôøng trong C++ hay khoâng ? 
 
3. Haõy vieát moät haøm  int counter(int array[], int size) ñeám soá caùc phaàn töû cuûa array 
coù gía trò  leû döôùi daïng ngoân ngöõ C, laøm theá naøo lieân keát vaøo chöông trình C++ coù söû 
duïng lôùp. 
 
4. Haõy taïo ra haøm chung traû veà giaù trò mode cuûa moät  maûng (giaù trò mode laø giaù trò 
baét gaëp nhieàu trong daõy) vaø soá laàn xuaát hieän cuûa noù. 
 
5. Haõy taïo haøm tính vaø traû veà giaù trò toång cuûa caùc phaàn töû  trong moät  maûng ? 
 
6. Haõy taïo ra haøm chung thöïc hieän moät soá giaûi thuaät saép xeáp (ñaõ hoïc trong moân Caáu 
truùc döõ lieäu vaø thuaät toaùn)  
 
7. Vieát chöông trình ñònh nghóa laïi lôùp stack ñeå noù löu tröõ moät caëp goàm hai ñoái töôïng 
coù kieåu döõ lieäu khaùc nhau. 
 
8. Vieát chöông trình ñònh nghóa laïi lôùp stack ñeå noù coù khaû naêng xöû lyù caùc loãi : full 
stack vaø empty stack . 
 
9. Vieát chöông trình ñònh nghóa laïi lôùp array trong ví du 7.3  chöông 3 , chuyeån lôùp 
naøy thaønh moät  lôùp chung. 
 
10. Vieát chöông trình ñònh nghóa haøm chung abs() trong ví du 3.7  chöông 1, sao cho 
noù tính vaø traû veà giaù trò tuyeät ñoái cuûa moät giaù trò thuoäc baát kyø kieåu naøo. 
 
 
 
 
 
 
 

background image

 

 

 
Chöông 11   
 
 

Phaùt trieån caùc heä thoáng höôùng ñoái töôïng 

 
 
 
 
 
 

• 

Giôùi thieäu 

 

• 

Caùc moâ hình höôùng-thuû tuïc 

 

• 

Caùc coâng cuï phaùt trieån höôùng-thuû tuïc 

 

• 

Moâ hình höôùng ñoái töôïng 

 

• 

Caùc kyù hieäu vaø ñoà thò höôùng ñoái töôïng 

 

• 

 Caùc böôùc phaân tích höôùng ñoái töôïng 

 

• 

Caùc böôùc thieát keá höôùng ñoái töôïng 

 

• 

Caøi ñaët 

 

• 

Moâ hình maãu 

 

• 

Toùm taét 

 

 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

338 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

339 

I/ Giôùi thieäu 

 
Caùc kyõ sö phaàn meàm ñaõ duøng nhieàu coâng cuï (tools), phöông phaùp (methods)  vaø thuû 
tuïc 

(procedures) khaùc nhau ñeå thöïc hieän tieán trình phaùt trieån phaàn meàm nhaèm xaây 

döïng caùc saûn phaåm phaàn meàm chaát löôïng cao vôùi hieäu suaát ngaøy caøng caûi tieán.  
 
Caùc phöông phaùp

 cung caáp khaùi nieäm “laøm nhö theá naøo” ñeå xaây döïng phaàn meàm 

trong khi caùc coâng cuï cung öùng caùc hoå trôï töï ñoäng vaø baùn töï ñoäng cho caùc phöông 
phaùp. Hoï söû duïng moïi giai ñoaïn phaùt trieån cuûa tieán trình phaùt trieån phaàn meàm, ñoù laø, 
laäp keá hoaïch, phaân tích, thieát keá, phaùt trieån vaø baûo trì.  
 
Caùc thuû tuïc 

phaùt trieån phaàn meàm tích hôïp caùc phöông phaùp vaø caùc coâng cuï laïi vôùi 

nhau vaø laøm cho söï phaùt trieån caùc heä thoáng phaàn meàm trôû neân hôïp lyù vaø hôïp thôøi. 
(hình 11.1). Chuùng cung caáp caùc nguyeân taéc chæ ñaïo nhö laøm theá naøo aùp duïng caùc 
phöông phaùp vaø coâng cuï, laøm theá naøo ñeå tieán haønh phaân phoái ôû moãi giai ñoaïn, caùc 
ñieàu khieån naøo seõ aùp duïng, vaø nhöõng coät moác naøo ñöôïc duøng ñeå ñaùnh giaù söï phaùt 
trieån. 
 
  

Software 

development   

     Procedures 

 

 

     Methods  

 

 

 

 

 

 

Tools 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Hình 11.1  Caùc thaønh toá phaùt trieån phaàn meàm 

 
Coù moät soá moâ hình phaùt trieån phaàn meàm, moãi moâ hình bao goàm moät taäp hôïp caùc 
phöông phaùp vaø coâng cuï khaùc nhau. Vieäc löïa choïn moät moâ hình phuï thuoäc vaøo baûn 
chaát cuûa moät öùng duïng, ngoân ngöõ laäp trình ñöôïc duøng, nhöõng ñieàu khieàn vaø phaân 
phoái ñöôïc yeâu caàu.  
 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

340 

Söï phaùt trieån moät heä thoáng hoaøn chænh khoâng nhöõng phuï thuoäc vaøo nhöõng phöông 
phaùp vaø kyõ thuaät thích hôïp maø coøn phuï thuoäc caùc raøng buoäc cuûa nhöõng nhaø phaùt 
trieån vaøo caùc ñoái töôïng cuûa heä thoáng. Moät heä thoáng hoaøn chænh phaûi laø : 

1.  thoaû maõn nhöõng yeâu caàu cuûa ngöôøi duøng. 
2.  trôû neân deå hieåu ñoái vôùi ngöôøi duøng vaø ngöôøi vaän haønh 
3.  trôû neân deå thao taùc 
4.  coù giao dieän toát 
5.  deã daøng chænh lyù 
6.  coù theå phaùt trieån ñöôïc 
7.  coù nhöõng ñieàu khieån baûo maät thích hôïp choáng laïi söï laïm duïng döõ lieäu 
8.  baét loãi vaø xöû lyù ngoaïi leä thaät haøi loøng 
9.  phaân phoái saûn phaåm theo ñuùng ngaøy giôø ñaõ aán ñònh 

 
Trong chöông naøy chuùng ta seõ xem xeùt moät vaøi caùch tieáp caän truyeàn thoáng ñöôïc öùng 
duïng roäng raõi trong phaùt trieån phaàn meàm vaø thaûo luaän moät vaøi yù töôûng hieän nay coù 
theå aùp duïng ñöôïc vaøo phaùt trieån phaàn meàm höôùng ñoái töôïng.  
 

II/ Caùc moâ hình höôùng-thuû tuïc 

 Prolem 

definition 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    Analysis 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Design 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

        Coding 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Testing 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Maintenance 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
Hình 11.2     Chu kyø soáng phaùt trieån phaàn meàm coå ñieån 

 

 

 

(moâ hình “thaùc nöôùc” nhuùng ñöôïc) 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

341 

Phaùt trieån phaàn meàm thöôøng ñöôïc moâ taû bôûi moät boä caùc traïng thaùi moâ taû caùc taùc vuï 
khaùc nhau bao goàm trong tieán trình phaùt trieån. Hình 11.2 minh hoaï chu kyø soáng phaàn 
meàm coå ñieån ñöôïc öùng duïng roäng raõi trong phaùt trieån höôùng-thuû tuïc (procedure-
oriented).  
 
Chu kyø soáng coå ñieån döïa treân moät moâ hình cô baûn, thoâng thöôøng laø moâ hình “thaùc 
nöôùc”. Moâ hình naøy coá gaéng laøm roõ nhöõng hoaït ñoäng coù theå nhaän bieát ñöôïc trong 
moät chuoãi caùc haønh ñoäng, moãi moät trong soá chuùng phaûi hoaøn taát tröôùc khi haønh ñoäng 
khaùc laïi baét ñaàu. Caùc hoaït ñoäng bao goàm, xaùc ñònh vaán ñeà, phaân tích caùc yeâu caàu, 
thieát keá, laäp trình, kieåm nghieäm, vaø baûo trì. Söï tinh cheá hôn nöõa cho moâ hình naøy 
bao goàm caùc böôùc laëp quay lui nhöõng giai ñoaïn tröôùc ñoù nhaèm keát hôïp chaët cheõ baát 
kyø söï bieán ñoåi naøo hoaëc caùc lieân keát coøn thieáu.  
 
Xaùc ñònh vaán ñeà 

: Haønh ñoäng naøy yeâu caàu moät ñònh nghóa chính xaùc veà vaán ñeà trong 

nhöõng thuaät ngöõ ñang duøng. Moät phaùt bieåu roõ raøng cuûa vaán ñeà laø moät quyeát ñònh cho 
söï thaønh coâng cuûa saûn phaåm. Noù khoâng chæ giuùp cho nhaø phaùt trieån maø coøn giuùp 
ngöôøi söû duïng hieåu vaàn ñeà ñöôïc toát hôn. 
 
Phaân tích caùc yeâu caàu 

: Ñieàu naøy bao truøm söï nghieân cöùu chi tieát veà nhöõng yeâu caàu 

cuûa caû ngöôøi duøng laãn saûn phaåm. Haønh ñoäng naøy laø moät böôùc cô baûn coù lieân quan 
ñeán “caùi gì” (What) cuûa heä thoáng nhö laø : 

• 

Nhöõng ñaàu vaøo cho heä thoáng laø caùi gì ? 

• 

Caùc tieán trình yeâu caàu caùi gì ? 

• 

Nhöõng ñaàu ra mong muoán seõ laø caùi gì ? 

• 

Nhöõng raøng buoäc (constraints) laø gì ? 

 

 

Thieát keá 

: pha thieát keá giaûi quyeát nhöõng quan nieäm khaùc nhau cuûa thieát keá heä thoáng 

nhö caáu truùc döõ lieäu, kieán truùc saûn phaåm, vaø caùc thuaät toaùn. Pha naøy chuyeån nhöõng 
yeâu caàu vaøo caùch bieåu dieãn (representation) cuûa saûn phaåm. Giai ñoaïn naøy traû lôøi caâu 
hoûi “How”. 
 
Laäp trình

 : Maõ hoaù coù lieân quan ñeán söï chuyeån dòch baûn thieát keá sang daïng maõ-maùy-

coù-theå-ñoïc-ñöôïc. Chi tieát hoaù baûn thieát keá, deã daøng hôn ñoù laø söï maõ hoaù vaø laøm cho 
tính tin caäy cuûa thieát keá ñöôïc toát hôn. 
 
Kieåm nghieäm

 : moät baûn maõ leänh ñöôïc vieát xong , caàn phaûi kieåm nghieäm nghieâm ngaët 

giuùp cho baûn maõ vaø keát quaû ñöôïc toát nhaát. Söï kieåm nghieäm coù theå laø moät vaøi modul 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

342 

rieâng leõ hoaëc coù khi laø toaøn boä heä thoáng. Noù yeâu caàu moät keá hoaïch chi tieát nhö kieåm 
tra caùi gì, khi naøo vaø laøm nhö theá naøo (what, when, how to test) 
 
Baûo trì

 : sau khi saûn phaåm ñaõ ñöôïc hoaøn chænh, noù coù theå phaûi chòu moät vaøi thay ñoåi. 

Ñieàu naøy thöôøng xaûy ra theo yeâu caàu cuûa ngöôøi duøng vaø cuûa caû moâi tröôøng ñieàu 
haønh, hoaëc moät loãi naøo ñoù trong saûn phaåm bò soùt trong quaù trình kieåm nghieäm.  Söï 
baûo trì baûo ñaûm raèng moïi thay ñoåi seõ ñöôïc keát hôïp chaët cheõ baát cöù luùc naøo thaáy caàn 
thieát. 
Moãi pha cuûa chu kyø soáng ñeàu coù muïc ñích vaø ñaàu ra. Ñaàu ra cuûa pha naøy seõ laø ñaàu 
vaøo cuûa pha tieáp theo. Baûng 11.1 seõ chiû ra caùc kieåu cuûa ñaàu ra 
 
 

Pha 

 

Ñaàu ra (outputs

 

Xaùc ñònh vaán ñeà 

 

* Phieáu phaùt bieåu cuûa vaán ñeà 

 

(why) 

 

* Taøi lieäu ñeà nghò cuûa döï aùn 

 

Phaân tích 

 

* Taøi lieäu yeâu caàu 

 

(what) 

 

* Baùo caùo khaû thi 

 

 

 

* Taøi lieäu ñaëc taû 

 

 

 

* Tieâu chuaån kieåm nghieäm ñöôïc coâng nhaän 

 

Thieát keá 

 

* Taøi lieäu thieát keá 

 

(how) 

 

* Thieát keá caùc tình huoáng cho kieåm nghieäm 

 

Maõ hoaù 

 

* Taøi lieäu maõ hoaù (chöông trình) 

 

(how) 

 

* Keá hoaïch kieåm nghieäm 

 

 

 

* Taøi lieäu cho ngöôøi duøng 

 

Kieåm nghieäm 

 

* Caùc maõ hoaù ñaõ ñöôïc kieåm nghieäm 

 

(what & how) 

 

* Caùc keát quaû kieåm nghieäm 

 

 

 

* Taøi lieäu cho heä thoáng 

 

Baûo trì 

 

* Caùc phieáu nhaät kyù baûo trì 

 

 

 

* Taøi lieäu caùc phieân baûn 

 

Baûng 11.1  Caùc ñaàu ra cuûa chu kyø soáng phaàn meàm coå ñieån 
 

Chu kyø soáng phaàn meàm, ñöôïc moâ taû ôû treân, thöôøng ñöôïc xem nhö kyõ thuaät phaân raõ 
chöùc naêng (the functional decomposition), ñöôïc bieát roäïng raõi nhö caùch tieáp caän töø 
treân xuoáng (top-down), hoaëc theo modun (modular). Kyõ thuaät phaân raõ chöùc naêng döïa 
treân söï theå hieän khoâng gian vaán ñeà vaø noù chuyeån sang khoâng gian lôøi giaûi nhö laø söï 
thoâng dòch moät taäp caùc haøm. Caùc haøm ñöôïc phaân raõ theo trình töï taêng daàn, nhöõng 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

343 

haøm ñôn giaûn nhaát seõ ñöôïc thöïc thi cuoái cuøng. Heä thoáng cuoái cuøng ñöôïc xem nhö 
moät taäp caùc haøm ñöôïc toå chöùc theo caáu truùc phaân caáp top-down .  
 
Cuõng coù moät vaøi thieáu soùt trong caùch tieáp caän top-down, tieáp caän phaân raõ chöùc naêng. 
Chuùng bao goàm : 

1.  Khoâng cho pheùp nhöõng thay ñoåi tieán hoaù trong phaàn meàm. 
2.  Heä thoáng ñöôïc ñaëc tröng bôûi moät haøm ñôn (a single function) ôû ñænh cuûa caây 

phaân caáp nhöng khoâng phaûi luùc naøo cuõng hoaøn toaøn ñuùng.  Trong nhieàu 
tröôøng hôïp thöïc teá caùc heä thoáng khoâng coù haøm  ñôn ôû ñænh. 

3.  Döõ lieäu khoâng ñöôïc xem laø ñaùng quan troïng. 
4.  Noù khoâng khuyeán khích vieäc taùi söû duïng maõ leänh ñaõ coù. 

 
 
 

III/ Caùc coâng cuï phaùt trieån höôùng-thuû tuïc 

 
Caùc coâng cuï phaùt trieån hieän nay coù theå phaân loaïi theo 3 theá heä. 
Caùc coâng cuï theá heä 1 ñöôïc phaùt trieån vaøo thaäp nieân 60 vaø 70 ñöôïc goïi laø caùc coâng cuï 
truyeàn thoáng. 
  
Caùc coâng cuï theá heä 2 ñöôïc giôùi thieäu vaøo cuoái thaäp nieân 70 vaø ñaàu thaäp nieân 80 daønh 
cho phaân tích vaø thieát keá caùc heä thoáng coù caáu truùc vaø do ñoù chuùng ñöôïc bieát nhö laø 
caùc coâng cuï coù caáu truùc. 
 
Caùc coâng cuï theá heä 3 ñöôïc giôùi thieäu vaøo cuoái thaäp nieân 80 cho ñeán nay daønh cho 
phaân tích vaø thieát keá caùc heä thoáng höôùng ñoái töôïng. 
 
Baûng 11.2 chæ cho thaáy moät soá coâng cuï thoâng duïng daønh cho caùc tieán trình phaùt trieån 
theo 3 chuûng loaïi. Phaàn naøy seõ giôùi thieäu toång quaùt moät vaøi coâng cuï thöôøng duøng ôû 
theá heä 1 vaø 2.  
 
Process 

  First 

generation 

  Second generation    Third generation 

Physical 
processes 

 System 

flowcharts 

  Context diagrams    Inheritance graphs 

Object-relationship 
charts 

 

   

   

   

Data 

 Layout 

forms   Data 

dictionary   Objects 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

344 

representation 

Grid charts 

Object dictionary 

 

   

   

   

Logic 
processes 

 Playscript 

English 
narrative 

 Decision  tables 

trees 
Data flow 
diagrams 

 Inheritance 

graphs 

Data flow diagrams 

 

   

   

   

Program 
representation 

 Program 

flowcharts 
I/O layouts 

 Structure 

charts 

Warrier/Orr 
diagrams 

  State change  diagrams 

Ptech diagrams 
Coad/Yourdon charts 

 
 

Baûng 11.2  Caùc coâng cuï phaùt trieån heä thoáng 

 
 
!"

Löu ñoà heä thoáng (System flowcharts) 

!"

Löu ñoà chöông trình (Program flowcharts) 

!"

Kòch baûn töøng giai ñoaïn (Playscripts) 

!"

Caùc khuoân daïng sô boä (Layout forms) cho vieäc nhaäp vaø xuaát keát quaû . 

!"

Bieåu ñoà (Grid charts) bieåu dieãn moái quan heä giöõa caùc modun cuûa heä thoáng. 

!"

Löôïc ñoà ngöõ caûnh (Context diagrams) bieåu dieãn ñaàu vaøo vôùi taøi nguyeân cuûa 
chuùng vaø ñaàu ra vôùi caùc ñích cuûa chuùng. 

!"

Löôïc ñoà doøng döõ lieäu (Data flow diagrams) bieåu dieãn doøng döõ lieäu giöõa caùc thaønh 
phaàn khaùc nhau cuûa heä thoáng 

!"

Töø ñieån döõ lieäu (Data dictionary) 

!"

Bieåu ñoà caáu truùc (Structures chart) bieåu dieãn ñoà thò caùc ñieàu khieån logic giöõa caùc 
modun cuûa heä thoáng. 

!"

Baûng quyeát ñònh (Decision table) moät baûng caùc tình huoáng baát ngôø daønh cho vieäc 
xaùc ñònh vaán ñeà vaø caùc haønh ñoäng ñeå thöïc hieän. 

!"

Caây quyeát ñònh (Decision tree) 

!"

Löôïc ñoà Warnier/Orr : moät bieåu ñoà phaân caáp haøng ngang söû duïng moät taäp caùc daáu 
moùc, maõ giaû (pseudo-code) vaø caùc kyù hieäu logic ñeå chæ caùc caáu truùc chöông trình. 

 
 
 
 
 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

345 

IV/ Moâ hình höôùng-ñoái töôïng 

 
Moâ hình höôùng-ñoái töôïng ñaët naëng treân lyù thuyeát heä thoáng toång quaùt nhö laø neàn taûng 
thuoäc veà khaùi nieäm. Moät heä thoáng coù theå ñöôïc xem nhö moät söï taäp hôïp caùc thöïc theå 
(entities), chuùng töông taùc vôùi nhau nhaèm ñaït ñeán muïc tieâu naøo ñoù

 (hình 11.3).  

 

Caùc thöïc theå coù theå bieåu dieãn caùc ñoái töôïng vaät lyù nhö caùc thieát bò hay con ngöôøi, vaø 
caùc khaùi nieäm tröøu töôïng nhö caùc file döõ lieäu hoaëc caùc haøm.  Trong phaân tích höôùng-
ñoái töôïng caùc thöïc theå ñöôïc goïi laø  caùc ñoái töôïng (objects). 

 
 

   PROCESS 

 
 
 
INPUT  

 

 

 

 

 

 

 

     OUTPUT 

 
 
 
 
 
 

Hình 11.3   Moät heä thoáng vôùi caùc quan heä-beân trong cuûa caùc thöïc theå 

 

Theo nhö teân goïi, moâ hình höôùng-ñoái töôïng ñaët ñeå taàm quan troïng nhaát vaøo caùc ñoái 
töôïng ñoù laø tính ñoùng goùi döõ lieäu vaø haøm. Chuùng ñoùng vai troø trung taâm trong moïi 
giai ñoaïn cuûa phaùt trieån phaàn meàm vaø do ñoù seõ toàn taïi ôû möùc cao söï goái leân nhau 
(overlap) vaø söï laëp ñi laëp laïi (iteration) giöõa caùc giai ñoaïn. Tieán trình phaùt trieån toaøn 
theå trôû thaønh söï tieán hoaù nhö trong töï nhieân. Baát kyø moät bieåu dieãn ñoà hoaï naøo cuûa 
caùc phieân baûn höôùng-ñoái töôïng cuûa chu kyø phaùt trieån phaàn meàm ñeàu phaûi löu taâm 
ñeán hai khía caïnh goái leân nhau vaø vaø söï laëp ñi laëp laïi. Keát quaû laø moâ hình “voøi phun 
nöôùc” (fountain model) ñaõ thay theá moâ hình “thaùc nöôùc coå ñieån” (hình 11.4).  

 
 
 
 
 
 
 

 
  Entity  

 

  Entity 

 
 

         Entity 

 
   
   Entity 

 

   Entity 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

346 

 Maintenance 

  Further 

development 

 
 

 

 

 

 
Application 

 
 
 
 

Object-oriented 

        OOP   

Objects 

 

programming    in 

program 

 

Object-oriented 

        OOD   

Objects 

 

design  

 

 

 

 

in solution space        

 

 
 

Object-oriented 

         OOA   

Objects 

 

analysis 

 

 

            

in problem space 

 
 
 

Hình 11.4   Moâ hình “voøi phun nöôùc”  trong phaùt trieån  

phaàn meàm höôùng-ñoái töôïng 

 

Phaân tích höôùng-ñoái töôïng 

(OOA) coù lieân quan ñeán caùc phöông phaùp cuûa caùc yeâu 

caàu ñaëc taû cuûa phaàn meàm theo thuaät ngöõ caùc ñoái töôïng cuûa theá giôùi thöïc, caùc haønh vi 
öùng xöû vaø caùc töông taùc cuûa chuùng. 

 

Thieát keá höôùng-ñoái töôïng 

(OOD) chuyeån nhöõng yeâu caàu cuûa phaàn meàm sang nhöõng 

ñaëc taû cho ñoái töôïng vaø caùc lôùp daãn xuaát phaân caáp töø ñoù caùc ñoái töôïng seõ ñöôïc taïo ra. 

 

Laäp trình  höôùng-ñoái töôïng 

(OOP) coù lieân quan ñeán caøi ñaët chöông trình trong moät 

ngoân ngöõ laäp trình höôùng ñoái töôïng nhö C++. 

 

Töông phaûn vôùi caùch tieáp caän phaân raõ chöùc naêng top-down, tieáp caän höôùng ñoái töôïng 
söû duïng caùc thieát keá top-down laãn bottom-up. Kyõ thuaät phaân raõ chöùc naêng töø treân 
xuoáng coù theå aùp duïng ñeå thieát keá caùc lôùp rieâng leõ trong khi heä thoáng cuoái coù theå 
ñöôïc xaây döïng vôùi söï trôï giuùp caùc modun lôùp söû duïng tieáp caän töø döôùi leân. 

 
 

Problem 

space    Objects 

defined 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

347 

 

      in 

problem 

space 

during 

analysis 

 

 

 

!

 

 

!

 

 

 

 

 

!

 

 

!

 

 
 
 
 
 
 

!

  

 

!

     !          ! Solution 

specific 

 

      objects 

defined 

  

 

                 !                    !  !  

during 

design 

Solution space 

 

 

Hình 11.5  Caùc taàng cuûa caùc ñaëc taû ñoái töôïng 

 
 

V/ Caùc kyù hieäu vaø ñoà thò höôùng ñoái töôïng 

 
Caùc kyù hieäu ñoà hoaï (graphical notations) laø phaàn khoâng theå thieáu cuûa baát kyø quaù 
trình thieát keá vaø phaùt trieån naøo, thieát keá höôùng ñoái töôïng cuõng vaäy. Chuùng ta caàn caùc 
kyù hieäu ñeå bieåu dieãn caùc lôùp, caùc ñoái töôïng, caùc lôùp con, vaø moái quan heä qua laïi cuûa 
chuùng. Thaät khoâng may, khoâng coù caùc kyù hieäu chuaån ñeå bieåu dieãn caùc ñoái töôïng vaø 
caùc töông taùc uûua chuùng. Moãi taùc giaû vaø caùc nhaø nghieân cöùu ñeàu coù caùch kyù hieäu 
rieâng cuûa mình. Döôùi ñaây laø moät soá kyù hieäu thoâng duïng , töø hình 11.6 ñeán 11.14 
 

1.  lôùp vaø ñoái töôïng 
2.  caùc theå hieän cuûa ñoái töôïng 
3.  message truyeàn thoâng giöõa caùc ñoái töôïng 
4.  quan heä keá thöøa 
5.  quan heä phaân loaïi 
6.  quan heä hôïp thaønh 
7.  bieåu ñoà phaân caáp thöù baäc 
8.  quan heä client-server 
9.  caùc tieán trình 

      Classname 

Classname  

 

 

Classname 

Function 1 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

348 

  

  Functions 

Data 

Data 

 
 

 

 

 

 

 

 

 

 

 

 

Functions 

 
 

 

 
 
 

 

 

 

 (a) 

   (b) 

    

 

 

 

(c) 

 
Hình 11.6  Caùc daïng khaùc nhau duøng bieåu dieãn lôùp/ñoái töôïng 
 
 
    

Person  Class 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 is-a 

  

is-a 

 

  is-a 

 

 

 

 

 

 

 

 
 

 John 

  

Hung 

 

  Ahmed 

 

 

 

 

 

 
objects 

 

Hình 11.7  Caùc theå hieän cuûa caùc ñoái töôïng 

 
 
 

Object A 

 

Object B 

 

 

 

 
 

 

 

 

 

 

Hình 11.8  message truyeàn thoâng giöõa caùc ñoái töôïng 
 

 A 

 

  

Base 

class 

Function 2 

Function 3 

data 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

349 

 

    

 

 

 

 
 

 

 B 

 

 

 
 

Derived class 

 

 

 

Hình 11.9  quan heä keá thöøa 
 

 

   Vehicle 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

a-kind-of 

 

 

 

 

 

 

 

 

 

Car 

   

Cycle 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(a) 

 
 

 

   Vehicle 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Car 

   

Cycle 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(b) 

Hình 11.10   

quan heä phaân loaïi 

 

  

House 

  

 

 

 

 

 

 

 

 

 

 

 

 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

350 

 

 

 

 

 

 

 

 

 

 

a-part-of 

 

 

 

 

 

 

 

 

 

Door 

    Window 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(a) 

 

 

  

House 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Door 

    Window 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(b) 

Hình 11.11   

quan heä hôïp thaønh 

 

 
       A    
 

 

 

 

 
 

 

 

   B  C  D 
 

 

 
 

 

 

 

 

  B1  B2      

 
Hình 11.12   

bieåu ñoà phaân caáp thöù baäc 

 
 
 
 

 X 

 

 

 

 

 
 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

351 

 

 

 

 

 

 

Server 

 

 

 

 

 

Client 

 

Hình 11.13   

quan heä client-server 

 
 

 Process 

 

 Process 

 

 

 
 
 

 

 

 Process 

 

 Process 

 

 

Hình 11.14   

caùc tieán trình 

(moät tieán trình coù theå coù töø 5 ñeán 7 ñoái töôïng tieâu bieåu) 

 
 

VI/ Caùc böôùc trong  phaân tích höôùng ñoái töôïng 

 
Phaân tích höôùng ñoái töôïng (OOA) cung caáp cho chuùng  ta moät cô cheá ñôn giaûn nhöhg 
ñaày söùc maïnh ñeå nhaän bieát caùc ñoái töôïng, caùc khoái xaây döïng (the buiding blocks) cuûa 
phaàn meàm ñaõ ñöôïc phaùt trieån.  
 
Vieäc phaân tích coù lieân quan veà cô baûn ñeán söï phaân raõ cuûa vaán ñeà thaønh caùc boä phaän 
caáu thaønh (component parts) cuûa noù vaø thieát laäp moät moâ hình logic nhaèm moâ taû caùc 
chöùc naêng cuûa heä thoáng. 
 
Tieáp caän phaân tích höôùng ñoái töôïng goàm coù caùc böôùc sau ñaây : 
1. Hieåu vaø naém vöõng vaán ñeà 
2. Phaùc thaûo nhöõng ñaëc taû yeâu caàu cuûa ngöôøi duøng vaø cuûa phaàn meàm 
3. Nhaän bieát caùc ñoái töôïng vaø caùc thuoäc tính cuûa chuùng 
4.  Nhaän bieát caùc dòch vuï trong ñoù moãi ñoái töôïng ñöôïc mong ñôïi cung caáp (giao 

dieän) 

5. Thieát laäp caùc quan heä noái lieàn vôùi nhau (coäng taùc - collaborations) giöõa caùc ñoái 

töôïng döôùi daïng caùc dòch vuï ñöôïc yeâu caàu vaø caùc dòch vuï ñaùp laïi (services 
rendered) .  

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

352 

 
Maëc duø, chuùng ta ñaõ chæ ra caùc taùc vuï nhö moät taäp caùc böôùc rieâng leû, ba böôùc cuoái 
ñöôïc thöïc hieän phuï thuoäc laãn nhau nhö hình 11.15 
 

  

   Problem 

definition 

 

 

 

 

 

 

 

 
 

 

 

 

  

  Requirement 

specifications 

 

 

 

 

 

 

 

 

 

 

 

 Objects 

in 

 

   

  

 problem 

space 

Identify 

Objects 

 

 

 

 

 

 

 

 
 

 

 

 

 

 

 

 

 

 

 

 

  

Identify 

services 

  

  Identify 

collaborations 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

   Design 

    

 

Hình 11.15  Caùc hoaït ñoäng cuûa phaân tích höôùng ñoái töôïng 

 
1/ Hieåu vaø naém vöõng vaán ñeà 

(problem understanding

Phaùt bieåu vaán ñeà phaûi roõ raøng vaø xaùc ñònh laïi döôùi daïng coâng ngheä heä thoáng maùy 
tính sao cho gôïi yù ra nhöõng lôøi giaûi döïa treân maùy tính. Phaùt bieåu vaán ñeà cung caáp cô 
sôû cho vieäc phaùc thaûo ñaëc taû caùc yeâu caàu cuûa caû ngöôøi duøng laãn phaàn meàm. 
 
2/ Ñaëc taû caùc yeâu caàu

 (requirements specification

Moät khi vaán ñeà ñöôïc xaùc ñònh roõ raøng, böôùc tieáp theo seõ bieát ñöôïc ñieàu gì heä thoáng 
ñöôïc yeâu caàu thöïc hieän. Ñieàu quan troïng ôû giai ñoaïn naøy laø taïo cho ñöôïc moät danh 
saùch caùc yeâu caàu cuûa ngöôøi duøng. Moät söï hieåu bieát thoâng suoát phaûi coù giöõa ngöôøi 
duøng vaø nhaø phaùt trieån (developer) vôùi caùi gì ñöôïc yeâu caàu. Döïa treân nhöõng yeâu caàu 
cuûa ngöôøi duøng, caùc ñaëc taû cho phaàn meàm seõ ñöôïc phaùc thaûo. Nhaø phaùt trieån phaûi 
dieãn ñaït heát söùc roõ raøng (what) :  

• 

Caùc ñaàu ra (outputs) ñöôïc yeâu caàu laø gì 

• 

Caùc tieán trình naøo ñöôïc goïi ñeå cho ra caùc ñaàu ra ñoù 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

353 

• 

Nhöõng ñaàu vaøo (inputs) caàn thieát ñoù laø gì 

• 

Nhöõng taøi nguyeân naøo ñöôïc yeâu caàu 

 
Nhöõng ñaëc taû naøy thöôøng duøng nhö moät tham khaûo ñeå kieåm nghieäm saûn phaåm cuoái 
nhaèm thöïc thi caùc taùc vuï mong ñôïi. 
 
3/ Nhaän bieát caùc ñoái töôïng 

(Identication of objects

Caùc ñoái töôïng thöôøng ñöôïc nhaän bieát duôùi daïng caùc ñoái töôïng theá giôùi thöïc hôn laø 
caùc ñoái töôïng tröøu töôïng. Do ñoù, nôi toát nhaát ñeå xem xeùt caùc ñoái töôïng laø ngay chính 
öùng duïng. ÖÙng duïng coù theå ñöôïc phaân tích baèng caùch söû duïng moät trong hai tieáp caän 
sau ñaây : 

• 

Caùc löôïc ñoà doøng döõ lieäu (DFD – Data flow diagrams)  

• 

Phaân tích theo nguyeân baûn (TA – Textual analysis

 
a/ Löôïc ñoà doøng döõ lieäu 
Moät öùng duïng coù theå bieåu dieãn döôùi daïng DFD chæ cho thaáy döõ lieäu seõ ñöôïc löu 
chuyeån töø nôi naøy ñeán nôi khaùc trong heä thoáng. Caùc kyù hieäu hoäp (boxe) vaø khung 
löu tröõ döõ lieäu (data store) trong DFD laø nhöõng öùng vieân toát cho bieåu dieãn caùc ñoái 
töôïng.  
 
Tieán trình noåi boït “bubbles” seõ töông öùng vôùi caùc thuû tuïc. Hình 11.16 minh hoaï moät 
löôïc ñoà doøng döõ lieäu ñieån hình. Noù cuõng ñöôïc bieát ñeán nhö moät ñoà thò doøng döõ lieäu 
(data flow graph) hoaëc moät bieåu ñoà noåi boït (bubble chart
 
Bookseller       

: nguôøi baùn saùch 

 

Order  

 

: ñôn ñaët haøng 

Process order 

: xöû lyù ñôn ñaët haøng 

Shipping instructions : chæ thò/lôøi chæ daãn veà vaän chuyeån haøng baèøng ñuôøng thuûy 
Stores/ Warehouse  :  cöûa haøng/ kho haøng 
Check credit status  : kieåm tra tình traïng cuûa theû tín duïng 
Shipment information : thoâng tin veà vieäc gôûi haøng leân taøu thuûy 
Shipping notice  

: lôøi baùo tröôùc/thôøi haïn veà vaän chuyeån haøng baèøng ñuôøng thuûy 

 
 

   

 Data store 

Books database 

 

 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

354 

   

 

boxe 

 
 
      

 

 

 

Shipping 

 

  Bookseller 

     Order 

Process 
order 

instructions  

Stores 

   

 

 
 
            Check credit status 

 

   

    Data store  Customer 

database 

 

 

 

 Shipping 

notice 

 
 
 

                Shipment  information 

  

 

Collect 

customer 

order 

 

 

 

 
Hình 11.16    DFD cho xöû lyù ñôn ñaët haøng vaø vaän chuyeån haøng cho cty saùch 
 
 
Moät DFD coù theå ñöôïc söû duïng ñeå bieåu dieãn moät heä thoáng ôû baát kyø möùc tröøu töôïng 
naøo. Laáy ví duï, DFD ñöôïc chæ ra ôû hình 11.16 coù theå môû roäng ñeå bao goàm nhieàu 
thoâng tin hôn nöõa (nhö caùc chi tieát traû tieàn) hoaëc coâ ñoïng laïi nhö minh hoaï trong hình 
11.17 ñeå trình baøy chæ cho moät noåi boït. 
 
 

 

 

Order  

 

 

      Instructions  

 

 

 
 

Hình 11.17  Löôïc ñoà doøng döõ lieäu cô sôû 

 

b/ Phaân tích theo nguyeân baûn 
Tieáp caän naøy döïa treân söï moâ taû nguyeân baûn cuûa vaán ñeà hoaëc lôøi giaûi ñöôïc ñeà xuaát. 
Moâ taû naøy coù theå laø moät trong hai caâu hoaëc moät trong hai ñoaïn tuøy thuoäc vaøo kieåu vaø 
söï phöùc taïp cuûa vaán ñeà. Caùc danh töø laø nhöõng boä chæ thò (indicator) toát cuûa caùc ñoái 
töôïng. Caùc teân coù theå ñöôïc phaân loaïi hôn nöõa nhö caùc danh töø chính xaùc (proper 
nouns

), caùc danh töø chung (common nouns), vaø caùc danh töø soá nhieàu (mass nouns

hoaëc caùc danh töø tröøu töôïng (abstract nouns). Baûng 11.3 chæ cho thaáy caùc kieåu khaùc 
nhau cuûa caùc danh töø vaø yù nghóa cuûa chuùng 

Customer 

Process order 

Warehouse 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

355 

 
  Type of noun   

Meaning 

 

Examples 

 Commun 

noun 

  Describe classes of things 

(entities) 

 Vehicle, customer, income 

(lôïi töùc), deduction 

  Proper noun 

  Names of specific things 

  Maruti car, John,  

ABC Company 

  Mass  or 

 abstract 
noun 

 

Describe a quality, 
quantity or an activity 
associated with a noun 

 Salary-income, 

House-loan, feet, 
traffic 

 

Baûng 11.3  Caùc kieåu cuûa caùc danh töø 

 
Ñieàu quan troïng caàn chuù yù laø ngöõ caûnh vaø ngöõ nghóa phaûi ñöôïc söû duïng ñeå xaùc ñònh 
caùc loaïi danh töø. Moät töø ñaëc thuø coù yù nghóa laø moät danh töø chung trong ngöõ caûnh naøy 
vaø moät danh töø soá nhieàu hoaëc moät danh töø tröøu töôïng trong ngöõ caûnh khaùc. 
 
Caùc tieáp caän naøy chæ laø moät söï höôùng daãn vaø khoâng phaûi laø caùc coâng cuï cuoái cuøng. 
Söï nhaän thöùc saùng taïo vaø khaû naêng tröïc giaùc cuûa caùc nhaø phaùt trieån coù kinh nghieäm 
ñoùng moät vai troø quan troïng trong vieäc nhaän bieát caùc ñoái töôïng. 
 
Ñeå söû duïng moät trong nhöõng caùch tieáp caän treân, caàn chuaån bò moät danh saùch caùc ñoái 
töôïng cho vaán ñeà öùng duïng. Ñieàu naøy phaûi bao goàm nhöõng taùc vuï sau : 
 

1.  Chuaån bò moät baûng ñoái töôïng 
2.  Nhaän bieát nhöõng ñoái töôïng coù lieân quan ñeán khoâng gian lôøi giaûi vaø nhöõng ñoái 

töôïng chæ lieân quan ñeán khoâng gian vaán ñeà (the problem space) . Caùc ñoái töôïng 
cuûa khoâng gian vaán ñeà seõ ôû beân ngoaøi phaïm vi cuûa phaàn meàm. 

3.  Nhaän bieát nhöõng thuoäc tính cuûa caùc ñoái töôïng khoâng gian lôøi giaûi (the 

solution space objects

). 

 
 
4/ Nhaän bieát caùc dòch vuï  
Moät khi caùc ñoái töôïng trong khoâng gian lôøi giaûi ñaõ ñöôïc nhaän bieát, böôùc tieáp theo laø 
nhaän bieát moät taäp hôïp caùc dòch vuï trong ñoù moãi ñoái töôïng töông öùng phaûi ñöôïc ñeà 
nghò.  

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

356 

Caùc dòch vuï ñöôïc nhaän bieát baèng caùch thaåm tra moïi ñoäng töø vaø caùc thaønh ngöõ ñoäng 
töø trong phaùt bieåu moâ taû vaán ñeà. Caùc ñoäng töø ñoù coù theå dieãn ñaït caùc haønh ñoäng hoaëc 
nhöõng bieán coá coù theå ñöôïc phaân loaïi theo baûng 11.4 sau 
 
  Type of verb   

Meaning 

 

Examples 

  Doing verbs 

  Operations 

  read, get, display, buy 

  Being verbs 

  Classifications 

  is an, belongs to  

  Having verbs    composition 

  has an, is part of 

 Compare 

vebs 

  Operations 

  is less than, 

is equal to 

  Stative vebs    Invariance-condition 

  to be present, are owned 

 

Baûng 11.4  Phaân loaïi caùc ñoäng töø 

 
 
5/ Thieát laäp caùc quan heä coäng taùc  
Böôùc naøy nhaän bieát caùc dòch vuï maø caùc ñoái töôïng cung caáp vaø thu nhaän (receive) . 
Coù theå duøng löôïc ñoà doøng thoâng tin IFD (information flow diagram) hoaëc löôïc ñoà 
quan heä-thöïc theå ERD (entity-relationship diagram) ñeå thu ñöôïc thoâng tin naøy. ÔÛ 
ñaây chuùng ta phaûi thieát laäp moái töông quan giöõa caùc dòch vuï vaø thoâng tin hieän taïi 
(caùc messages) baèng caùch truyeàn thoâng. 
 
 

VII/ Caùc böôùc thieát keá höôùng ñoái töôïng 

 
Thieát keá coù lieân quan ñeán vieäc aùnh xaï cuûa caùc ñoái töôïng trong khoâng gian vaán ñeà 
sang caùc ñoái töôïng trong khoâng gian lôøi giaûi vaø taïo ra moät caáu truùc toång theå (moâ hình 
kieán truùc) vaø caùc moâ hình tính toaùn cuûa heä thoáng. 
 
Giai ñoaïn naøy thöôøng duøng caùch tieáp caän bottum-up ñeå xaây döïng caáu truùc cuûa heä 
thoáng vaø tieáp caän phaân raõ chöùc naêng top-down ñeå thieát keá caùc haøm thaønh vieân cuûa 
lôùp maø chuùng cung caáp caùc dòch vuï. Ñoù laø ñieàu heát söùc quan troïng ñeå xaây döïng caáu 
truùc phaân caáp, ñeå nhaän bieát caùc lôùp tröøa töôïng, vaø ñeå ñôn giaûn hoaù nhöõng truyeàn 
thoâng (lieân laïc) beân trong ñoái töôïng (the inter-object communications
 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

357 

Vieäc söû duïng laïi caùc lôùp töø caùc thieát keá tröôùc ñoù, phaân loaïi caùc ñoái töôïng vaøo caùc heä 
thoáng con vaø xaùc ñònh caùc giao thöùc thích hôïp seõ laø moät soá caùc quan taâm cuûa giai 
ñoaïn thieát keá. 
 
Tieáp caän thieát keá höôùng ñoái töôïng coù theå bao goàm caùc böôùc sau : 

1.  Xem xeùt caùc ñoái töôïng ñaõ taïo ra trong pha phaân tích 
2.  Ñaëc taû caùc phuï thuoäc lôùp (class dependencies
3.  Toå chöùc söï phaân caáp lôùp 
4.  Thieát keá caùc lôùp 
5.  Thieát keá caùc haøm thaønh vieân 
6.  thieát keá chöông trình qua moät ngoân ngöõ laäp trình cuï theå 

 
 
1/ Xem xeùt caùc ñoái töôïng trong khoâng gian vaán ñeà 
Moät vaøi höôùng daãn giuùp tieán trình xem xeùt ñoù laø : 

1.  Neâùu chæ moät ñoái töôïng laø caàn thieát cho moät dòch vuï (hoaëc moät hoaït ñoäng), thì 

noù thao taùc chæ treân ñoái töôïng ñoù. 

2.  Neáu coù hai hoaëc nhieàu ñoái töôïng ñöôïc yeâu caàu cho moät hoaït ñoäng ñang dieãn 

ra, thì noù caàn nhaän bieát phaàn vieäc rieâng cuûa ñoái töôïng naøo phaûi ñöôïc nhaän ra 
ñeå haønh ñoäng. 

3.  Neáu moät hoaït ñoäng yeâu caàu söï hieåu bieát nhieàu hôn moät kieåu naøo ñoù cuûa caùc 

ñoái töôïng, thì hoaït ñoäng khoâng dính líu veà maët chöùc naêng vaø caàn phaûi loaïi boû. 

 
Aùp duïng caùc höôùng daãn naøy seõ giuùp chuùng ta tinh loïc caùc dòch vuï cuûa caùc ñoái töôïng. 
Hôn nöõa, caùc ñoái töôïng dö thöøa vaø khoâng lieân quan seõ ñöôïc boû ñi, caùc dòch vuï coù  
cuõng nghóa ñöôïc keát hôïp laïi vaø caùc teân cuûa caùc thao taùc (caùc haøm) ñöôïc caûi tieán 
nhaèm bieåu hieän trong saùng caùc daïng xöû lyù ñöôïc yeâu caàu. 
 
2/ Caùc phuï thuoäc lôùp 
Phaân tích caùc quan heä giöõa caùc lôùp laø trung taâm cuûa caáu truùc moät heä thoáng. Do ñoù, 
noù quan troïng ñeå nhaän bieát caùc lôùp thích hôïp ñeå bieåu dieãn caùc ñoái töôïng trong khoâng 
gian lôøi giaûi vaø thieát laäp moái quan heä cuûa chuùng. Nhöõng quan heä chuû yeáu ñoùng vai 
troø quan troïng trong ngöõ caûnh cuûa thieát keá ñoù laø : 

1.  quan heä keá thöøa 
2.  quan heä bao haøm 
3.  quan heä söû duïng  

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

358 

a/ Quan heä keá thöøa laø moái quan heä cao nhaát coù theå ñöôïc bieåu dieãn trong C++. Ñoù laø 
caùch bieåu dieãn ñaày naêng löïc veà moái quan heä phaân caáp thöù baäc tröïc tieáp. Neáu xem  
hình 11.12 minh hoïa lôùp cô sôû A vaø caùc lôùp keá thöøa cuûa noù thì baûng quan heä keá thöøa 
seõ ñöôïc chæ ra ôû baûng 11.5 nhö sau : 
 

 Class 

 

Depends 

on 

 A 

 

 B 

 

 C 

 

 D 

 

 B1 

 

 B2 

 

 
 

 

Baûng 11.5  Baûng quan heä keá thöøa 

 
b/ Quan heä bao haøm coù nghóa laø duøng moät ñoái töôïng cuûa lôùp nhö laø thaønh vieân cuûa 
lôùp khaùc. Ñaây laø kyõ thuaät “daâng taëng” vaø kyõ thuaät loaïi tröø ñeå duøng keá thöøa lôùp. 
Nhöng noù thöôøng ñoøi hoûi söï kheùo leùo ñeå choïn löïa giöõa hai kyõ thuaät.  
 
Thoâng thöôøng, neáu caàn ñeå quaù taûi caùc thuoäc tính hoaëc caùc haøm, thì keá thöøa laø söï löïa 
choïn laø toát nhaát. Maët khaùc, neáu chuùng ta muoán bieåu dieãn moät ñaëc tính bôûi söï ña daïng 
cuûa caùc kieåu, thì quan heä bao haøm laø phöông phaùp caàn ñeán. Moät luùc naøo ñoù chuùng ta 
caàn duøng moät ñoái töôïng nhö moät thaønh vieân thì khi ñoù chuùng ta caàn gôûi moät thuoäc 
tính cuûa lôùp nhö moät ñoái soá ñeán haøm taïo cuûa lôùp khaùc. Lôùp “khaùc” phaûi coù moät ñoái 
töôïng thaønh vieân ñöôïc bieåu dieãn nhö ñoái soá. 
 
Tính keá thöøa bieåu dieãn quan heä is_a vaø quan heä bao haøm bieåu dieãn quan heä has_a . 
 
c/ Quan heä söû duïng  
Ví duï, lôùp A coù theå duøng lôùp B vaø C qua moät vaøi caùch 
 

A ñoïc (reads) moät thaønh vieân cuûa B 

 

A goïi (calls) moät thaønh vieân cuûa C 

 

A taïo ra (creates) B söû duïng toaùn töû new 

 
Söï hieåu bieát veà caùc quan heä nhö theá laø quan troïng ñeå thieát keá moät chöông trình. 
 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

359 

3/ Toå chöùc söï phaân caáp thöù baäc lôùp 

 bao goàm söï nhaän bieát caùc thuoäc tính vaø caùc 

haøm chung nhaát giöõa moät nhoùm caùc lôùp coù quan heä nhau vaø keát hôïp chuùng vaøo daïng 
moät lôùp môùi naøo ñoù. Lôùp môùi naøy seõ phuïc vuï nhö moät sieâu lôùp (super class) vaø 
nhöõng lôùp khaùc nhö laø caùc lôùp phuï thuoäc (vôùi nhöõng thuoäc tính daãn xuaát töø sieâu lôùp). 
Lôùp môùi coù theå hoaëc khoâng theå coù yù nghóa cuûa ñoái töôïng bôûi chính noù. Neáu moät ñoái 
töôïng ñöôïc taïo ra thuaàn tuùy ñeå keát hôïp caùc thuoäc tính chung, noù ñöôïc goïi laø lôùp tröøu 
töôïng. 
 
Tieán trình naøy coù theå laëp laïi ôû caùc möùc khaùc nhau cuûa söï tröøu töôïng vôùi moät muïc 
ñích duy nhaát cuûa vieäc baønh tröôùng caùc lôùp.  
 
Ví duï hình 11.18 minh hoïa tieán trình laëp hai möùc. 
 

   

B   X     Y   

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

       A  B  C  D  E 

 
(a) Caùc ñoái töôïng trong    

(b) Caây phaân caáp möùc thöù nhaát 

khoâng gian lôøi giaûi 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 

 

 

 

 

 

 

 X     Y   

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

A  B  C  D  E 

 
 

 

 

(c) Caây phaân caáp möùc thöù hai 

 

Hình 11.18  Caùc möùc cuûa phaân caáp thöù baäc lôùp 

 
Tieán trình cuûa toå chöùc lôùp coù theå keát quaû cuoái cuøng trong moät moâ hình caây ñôn 
(single-tree model) hoaëc moâ hình röøng caây (forest). Hình 11.19 
 
 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

360 

4/ Thieát keá caùc lôùp 
Chuùng ta ñaõ nhaän bieát caùc lôùp, caùc thuoäc tính cuûa noù, vaø moät taäp hôïp toái thieåu caùc 
thao taùc ñöôïc yeâu caàu qua khaùi nieäm moät lôùp ñöôïc bieåu dieãn. Baây giôø chuùng ta haõy 
xem xeùt caùc chi tieát ñaày ñuû maø moãi lôùp bieåu dieãn. Vaán ñeà quan troïng laø quyeát ñònh 
nhöõng haøm naøo ñeå xaây döïng lôùp. Vôùi moät lôùp thoâng thöôøng, caàn coù caùc haøm thöïc 
hieän caùc chöùc naêng sau ñaây : 
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(a) moâ hình caây ñôn 

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(b) moâ hình röøng caây 

 
Hình 11.19   Toå chöùc caùc lôùp 

 

1.  caùc haøm quaûn lyù lôùp 

• 

moät ñoái töôïng ñöôïc taïo ra nhö theá naøo ? 

• 

moät ñoái töôïng ñöôïc huûy nhö theá naøo ? 

2.  caùc haøm thöïc thi lôùp 

• 

nhöõng thao taùc naøo seõ ñöôïc thöïc hieän treân kieåu döõ lieäu cuûa lôùp ? 

 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

361 

3.  caùc haøm truy xuaát lôùp 

• 

chuùng ta seõ laáy thoâng tin töø caùc bieán beân trong cuûa lôùp nhö theá naøo ? 

4.  caùc haøm tieän ích lôùp 

• 

chuùng ta seõ xöû lyù loãi nhö theá naøo ? 

 
Moät vaán ñeà nöõa caàn xem xeùt ñeán : 

1.  Loaïi ñieàu khieãn truy xuaát naøo ñöôïc yeâu caàu cho lôùp cô sôû ? 
2.  Caùc haøm naøoseõ laø haøm aûo ? 
3.  Caùc lôùp thö vieän naøo seõ duøng trong moät lôùp ? 

Vieäc thieát keá caùc lôùp rieâng leõ coù aûnh huôûng khaù lôùn ñeán chaát löôïng cuûa phaàm meàm. 
Sau ñaây laø moät vaøi nguyeân taéc chæ ñaïo ñöôïc duøng ñeå xem xeùt  trong khi thieát keá moät 
lôùp : 

1.  giao tieáp chung cuûa lôùp chæ giao cho moät haøm cuûa lôùp. 
2.  moät ñoái töôïng cuûa moät lôùp khoâng theå gôûi message tröïc tieáp ñeán thaønh vieân 

cuûa lôùp khaùc. 

3.  moät haøm ñöôïc khai baùo laø public chæ khi naøo noù ñöôïc ñoøi hoûi söû duïng bôûi caùc 

ñoái töôïng cuûa lôùp. 

4.  moãi haøm truy xuaát, thay ñoåi hoaëc caû hai ñeán moät vaøi döõ lieäu cuûa lôùp maø noù 

bieåu dieãn. 

5.  moät lôùp coù theå phuï thuoäc vaøo moät vaøi lôùp khaùc neáu coù theå. 
6.  söï töôngtaùc giöõa caùc lôùp phaûi töôøng minh. 
7.  moãi lôùp phuï thuoäc (subordinate class) phaûi ñöôïc thieát keá nhö moät söï chuyeân 

moân hoaù cuûa lôùp cô sôû vôùi moät muïc ñích duy nhaát boå sung caùc ñaëc tính phuï. 

8.  lôùp treân cao nhaát cuûa moät caáu truùc neân bieåu dieãn nhö moâ hình lôùp tröøu töôïng.  

 
 
5/ Thieát keá caùc haøm thaønh vieân 
Ñeán ñaây chuùng ta ñaõ nhaän bieát ñöôïc : 

1.  Caùc lôùp vaø caù ñoái töôïng 
2.  caùc thaønh vieân döõ lieäu 
3.  caùc giao dieän 
4.  caùc phuï thuoäc vaø 
5.  phaân caáp thöù baäc lôùp 

 
Luùc naøy caàn xem xeùt vieäc thieát keá caùc haøm thaønh vieân. Caùc haøm thaønh vieân ñònh 
nghóa caùc thao taùc duøng ñeå thöïc hieän treân döõ lieäu cuûa ñoái töôïng. Caùc haøm naøy cuõng 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

362 

gioáng nhö baát kyø caùc haøm ngoân ngöõ C vaø do ñoù chuùng ta coù theå söû duïng kyõ thuaät 
phaân raõ chöùc naêng top-down ñeå thieát keá chuùng nhö chæ ra trong hình 11.20 
 
Chuùng ta cuõng coù theå aùp duïng caùc kyõ thuaät thieát keá caáu truùc (structured design) cho 
moãi modun. Caùc kyõ thuaät thieát keá caáu truùc cô sôû ñöôïc hoå trôï bôûi C++ ñöôïc chæ ra ôû 
hình 11.21.  Chuùng ta coù theå thöïc thi chuùng trong keát hôïp baát kyø naøo vaø keå caû söû 
duïng khaùi nieäm moät-ñaàu vaøo, moät-ñaàu ra (one-entry, one-exit) . 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Hình 11.20  Thieát keá top-down cuûa caùc haøm 

 
 
 
 
 
 

 

 

 

 

 

 

 

 

 

 

 

 Function 

 

 

 

 

 

 

 

 

 

 

   Data 

 

 

 

 

 

 

 

 Function 

 

 

 

 

 

 

 

 

 

 

 

 

 

Object 

 
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 

 

 

 

 

 

 B    C  D  

 

 

 

 

 

 

 
 

 

 

 

 

  B1  B2    D1  D2 

 

 

 

 

 

 

 
 

 

 

 

 

   

B12 

    

D12 

 

 

 

 

 

Modules of function 2 

 

 

 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

363 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Hình 11.21  Caùc kyõ thuaät thieát keá caáu truùc 

 

  

Entry 

 

 

 

 

 

 

 

 

 

  

Task 

 

 

 

 

 

 

 

 

 

  

Task 

 

 

 

 

 

 

 

 

 

  

Task 

 

 

 

 

 

 

 

 

 

  

Exit 

 

 

 

 

 

 

 

 

 

 (a) 

Sequence 

 

 

     Entry    
 

 

 

 

 

 

  True 

False 

 

 

 

 

 

Test    

 

 

 

 

 

 

 

Task 

   

Task 

 

 

 

 

 

 

 

 

 

 

 

 
 

   

Exit 

  

 

 

 

 

 

 

  

(b) 

Selection 

 

     Entry    
 

 

 

 
 
 

 

 

 

 

 

 

 

 

 

 

 

Test 

 Task 

 

 

 

 

 

 

 

 

 

 

 

 

 

   

Exit 

  

  

(c) 

Loop 

 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

364 

6/ Thieát keá chöông trình  qua moät ngoân ngöõ laäp trình cuï theå 
 
Moãi chöông trình C++ phaûi bao goàm maõ haøm main() ñöôïc goïi laø chöông trình ñieàu 
khieån (driver program) Thöïc thi chöông trình baét ñaàu vaø keát thuùc ôû ñaây. Chöông 
trình ñieàu khieån chòu traùch nhieäm chính veà  : 

1.  nhaän caùc döõ lieäu töø ngöôøi duøng 
2.  taïo caùc ñoái töôïng töø nhöõng ñònh nghóa lôùp 
3.  saép seáp söï truyeàn thoâng giöõa caùc ñoái töôïng nhö moät söï tuaàn töï caùc message ñeå 

goïi caùc haøm thaønh vieân 

4.  hieån thò keát quaû xuaát theo daïng thöùc cuûa ngöôøi duøng yeâu caàu 

 
Moïi hoaït ñoäng bao goàm xöû lyù trong khi thöïc thi keát quaû chöông trình ñeàu töø nhöõng 
taùc ñoäng laãn nhau cuûa caùc ñoái töôïng. Moät thieát keá chính yeáu quyeát ñònh thöïc hieän thöù 
töï logic cuûa caùc message gôûi ñeán. 
 
Chöông trình ñieàu khieån laø coång noái vôùi ngöôøi duøng. Do ñoù, thieát keá giao dieän ngöôøi 
duøng caàn phaûi caân nhaéc thích ñaùng trong khi thieát keá chöông trình. Heä thoáng ñöôïc 
thieát keá sao cho coù tính thaân thieän ñeå ngöôøi duøng thao taùc ñöôïc töï nhieân vaø thoaûi maùi 
nhaát. 
 
 

VIII/ Caøi ñaët 

Caøi ñaët (implementation) bao goàm maõ hoaù vaø kieåm nghieäm. Maõ hoaù (coding) goàm coù 
vieát maõ leänh cho caùc lôùp, haøm thaønh vieân vaø chöông trình main() giöõ nhieäm vuï ñieàu 
khieån trong chöông trình. Vieäc maõ hoaù trôû neân deã daøng khi vieäc thieát keá chi tieát ñaõ 
ñöôïc thöïc hieän heát söùc caån thaän. 
 
Khoâng moät chöông trình naøo coù theå laøm vieäc toát trong laàn ñaàu tieân. Vì vaäy vieäc kieåm 
nghieäm (testing) chöông trình tröôùc khi duøng laø phaàn thieát yeáu cuûa tieán trình phaùt 
trieån phaàn meàm. Keá hoaïch kieåm nghieäm chi tieát phaûi ñöôïc phaùc thaûo laø kieåm 
nghieäm caùi gì, khi naøo vaø nhö theá naøo. Caùc giao tieáp lôùp  caùc phuï thuoäc lôùp laø nhöõng 
khía caïnh qua n troïng cuûa vieäc kieåm nghieäm. Muïc ñích cuoái cuøng cuûa kieåm nghieäm 
laø xem xeùt heä thoáng thöïc thi nhöõng coâng vieäc ñònh truôùc coù laøm thoaû maõn hay khoâng.  
 
 
 

IX/ Moâ hình nguyeân maãu (prototyping paradigm) 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

365 

 
Haàu heát caùc baøi toaùn öùng duïng trong theá giôùi thöïc ñeàu phöùc taïp vaø do ñoù caáu truùc 
cuûa heä thoáng trôû neân quaù lôùn ñeå thöïc hieän caùc yeâu caàu chính xaùc luùc ban ñaàu. Moät 
vaøi thaønh phaàn chæ bieát ñöôïc roõ raøng luùc chuùng ta xaây döïng vaø kieåm nghieäm heä 
thoáng. Sau khi moät heä thoáng ñoà soä ñöôïc hoaøn thaønh, vieäc hôïp nhaát caùc ñaëc ñieãm coù 
theå daãn ñeán vieäc “thieáu soùt“ chuùng luùc kieåm nghieäm hoaëc caùc giai ñoaïn cuûa öùng 
duïng phaûi traû giaù ñaét vaø tieâu toán quaù nhieàu thôøi gian. Caùch toát nhaát ñeå am hieåu thieát 
keá heä thoáng vaø phaân chia chuùng tröôùc khi xaây döïng heä thoáng hoaøn chænh ñoù laø xaây 
döïng vaø kieåm nghieäm moät moâ hình laøm vieäc cuûa heä thoáng ñöôïc ñeà xuaát. Moät heä 
thoáng moâ hình ñöôïc bieát roäng raõi nhö moät nguyeân maãu (prototype) vaø söï tieán haønh 
ñöôïc goïi laø prototyping. Töø khi caùch tieáp caän phaân tích vaø thieát keá höôùng ñoái töôïng 
ñöôïc giôùi thieäu,  noù trôû neân phuø hôïp nhaát ñoái vôùi moâ hình nguyeân maãu (prototyping 
paradigm

) ñöôïc minh hoïa trong hình 11.22 

 
 
 
  
 
 

 
 
 
 
 
 
 
 
 
 

 
 
 
 

Hình 11.22  moâ hình nguyeân maãu  

 
Moät nguyeân maãu laø moät phieân baûn keát vaûy haï thaáp daàn (scaled  down)  cuûa heä thoáng 
vaø coù theå khoâng coù tieâu chuaån thöïc thi nghieâm ngaët vaø caùc yeâu caàu taøi nguyeân. Caùc 

 

System 

Specifications 

 

 

 

 

 

 

 

 

 

 

 

 Outline 

requirements 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

Design 

prototype 

model 

 

 

 

 

 

 

 

  

 

 

 

Build 

Prototype 

 

 

 

 

 

 

 

 

 

 

 

 

 
 

 

 

 

 

       

Make 

detailed 

design 

 

 

 

 

 

 

 

 

 

 

 

 

Full 

System 

 

 

 

 

 

Evaluate 

prototype 

performance 

 

 

 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

366 

nhaø phaùt trieån vaø caùc khaùch haøng ñoàng yù theo caùc “ñaëc taû ñöôøng neùt ñaïi cöông” 
(outline specifications) cuûa heä thoáng vaø thieát keá nguyeân maãu ñöôïc ñeà nghò vôùi caùc 
yeâu caàu ñöôøng neùt ñaïi cöông vaø caùc taøi nguyeân coù theå coù. Nguyeân maãu seõ ñöôïc xaây 
döïng vaø ñaùnh giaù. Ñieàu quan taâm chính khoâng phaûi laø nguyeân maãu maø laø söï thöïc thi 
cuûa chuùng duøng ñeå tinh chænh caùc ñaëc taû yeâu caàu. 
 
Caùc nguyeân maãu cung caáp moät cô hoäi ñeå thöû nghieäm vaø phaân tích caùc khía caïnh 
khaùc nhau cuûa heä thoáng nhö caáu truùc heä thoáng, thieát keá beân trong, caùc yeâu caàu phaàn 
cöùng vaø caùc yeâu caàu heä thoáng cuoái cuøng. Lôïi ích cuûa caùch tieáp caän nguyeân maãu laø : 
 

1.  Chuùng ta coù theå trình dieãn caùc ñaëc taû coù theå hieåu ñöôïc, chuùng hôïp lyù vaø ñaày 

ñuû ñeå coù theå chaáp nhaän ñöôïc. 

2.  Ngöôøi duøng coù theå hieåu ñöôïc ñieàu gì ñaõ xaûy ra. 
3.  Nhöõng thay ñoåi veà baûo trì ñöôïc yeâu caàu laø toái thieåu khi heä thoáng ñaõ caøi ñaët 

roài. 

4.  Caùc kyõ sö phaùt trieån coù theå laøm vieäc töø moät taäp hôïp caùc ñaëc taû maø chuùng ñaõ 

ñöôïc kieåm nghieäm vaø chaáp thuaän. 

 
Prototype coù theå nghóa laø ñaõ qua kinh nghieäm. Thöôøng haàu heát chuùng khoâng ñöôïc 
ñieàu chænh vaøo moät saûn phaåm. Tuy nhieân, ñoâi khi coù theå ñieàu chænh moät prototype 
vaøo saûn phaåm cuoái neáu söï thaän troïng thích ñaùng ñöôïc thöïc hieän trong vieäc taùi thieát 
keá prototype. Caùch tieáp caän toát nhaát ñoù laø haõy vöùt boû prototype sau khi söû duïng. 
 
 
 

X/ Toùm taét 

 
Chuùng ta ñaõ thaûo luaän caùc khía caïnh khaùc nhau cuûa phaân tích vaø thieát keá höôùng ñoái 
töôïng. Haõy nhôù raèng, ñoù khoâng phaûi laø caùch tieáp caän luoân luoân ñem laïi tính ñuùng 
ñaén. Baïn phaûi xem xeùt caùc yù töôûng ñöôïc ñeà xuaát ôû chöông naøy xem noù chæ laø caùc 
nguyeân taéc chæ ñaïo vaø haõy duøng nhöõng kinh nghieäm, söï ñoåi môùi, vaø söï saùng taïo cuûa 
baïn trong moïi luùc coù theå. 
 
 
 
Sau ñaây laø moät vaøi ñieåm baïn neân suy nghó vaø tieáp tuïc ñoåi môùi : 

1.  Thieát laäp caùc muïc ñích roõ raøng vaø thöïc teá 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

367 

2.  Coá gaéng duøng caùc heä thoáng ñaõ toàn taïi nhö laø caùc ví duï hoaëc moâ hình maãu ñeå 

phaân tích heä thoáng cuûa baïn. 

3.  Söû duïng caùc lôùp ñeå bieåu dieãn caùc khaùi nieäm. 
4.  Haõy luoân nhôù raèng heä thoáng maø baïn taïo ra phaûi coù tính linh ñoäng, khaû chuyeån 

vaø coù theå môû roäng. 

5.  Haõy taïo caùc söu lieäu roõ raøng cho baát cöù ñieàu gì cho heä thoáng cuûa baïn. 
6.  Coá gaéng söû duïng laïi caùc haøm vaø lôùp ñaõ coù saün. 
7.  Baûo veä vöõng chaéc caùc haøm ñaõ ñònh kieåu baát cöù luùc naøo coù theå ñöôïc. 
8.  Söû duïng caùc prototype baát cöù luùc naøo coù theå ñöôïc. 
9.  Haõy laøm cho phuø hôïp giöõa thieát keá vaø kieåu laäp trình 
10. Haõy giöõ cho heä thoáng saùng suûa, ñôn giaûn, goïn nhoû vaø coù hieäu quaû  

 
 
 
Baøi taäp chöông 11 
 
 
1. Haõy lieät keâ 5 ñaëc tính quan troïng nhaát, theo yù kieán cuûa baïn, maø caùc nhaø phaùt trieån 
phaàn meàm caàn löu taâm khi phaùt trieån moät heä thoáng ? 
 
2. Haõy moâ taû taïi sao vieäc kieåm nghieäm moät phaàn meàm laø quan troïng ? 
 
3. Theo baïn baûo trì phaàn meàm nghóa laø ? Vieäc thöïc hieän nhö theá naøo vaø luùc naøo ? 
  
4. Ai laø “ngöôøi chôi” chính trong moãi giai ñoaïn cuûa chu kyø soáng phaùt trieån heä thoáng 

 
5. Coù caàn thieát nghieân cöùu caùc heä thoáng ñaõ toàn taïi trong caùc giai ñoaïn phaân tích ? 
Neáu coù, taïi sao ? Neáu khoâng, taïi sao ? 
 
6. Nhöõng giôùi haïn cuûa chu kyø soáng phaùt trieån heä thoáng coå ñieån laø gì ? 
 
7. Haõy thaûo luaän, “Tieán trình phaùt trieån heä thoáng laø tieán trình laëp ñi laëp laïi” . 
 
8. Haõy phaân bieät giöõa moâ hình thaùc nöôùc vaø moâ hình voøi phun nöôùc ? 
 

background image

Chöông 11   Phaùt trieån heä thoáng höôùng ñoái töôïng

 

 

 

368 

9. Haõy phaân bieät giöõa phaân tích caùc heä thoáng höôùng ñoái töôïng vaø thieát keá heä thoáng 
höôùng ñoái töôïng ? Caùi naøo yeâu caàu taøi naêng saùng taïo hôn cuûa nhaø phaùt trieån heä thoáng 

 
10. Haõy phaân bieät giöõa nhöõng ñieàu sau : 

(a) quan heä phaân loaïi (classification) vaø quan heä hôïp thaønh (composition
(b) quan heä keá thöøa vaø quan heä client-server 
(c) Caùc ñoái töôïng trong khoâng gian vaán ñeà vaø trong khoâng gian lôøi giaûi 
(d) Caùc löôïc ñoà doøng döõ lieäu vaø bieåu ñoà phaân caáp thöù baäc 

 
11. Thaûo luaän öùng duïng veà caùc kyõ thuaät thieát keá coù caáu truùc trong laäp trình höôùng ñoái 
töôïng. 
 
12. Caùc vaán ñeà tieâu chuaån naøo ñöôïc xem xeùt trong khi thieát keá caùc chöông trình ñieàu 
khieån ? Taïi sao ? 
 
13. Giaûi thích lôøi nhaän xeùt “khoâng moät chöông trình naøo coù theå chaïy toát trong laàn 
ñaàu tieân” 
14. Prototyping laø gì ? Noù giuùp cho vieäc caûi tieán thieát keá heä thoáng nhö theá naøo ? 
 
15. Caùc phaùt bieåu sau ñaây laø ñuùng hay sai : 

(a)  Moät söï xem xeùt quan troïng trong khi thieát keá moät heä thoáng môùi chính laø ngöôøi 

duøng cuoái. 

(b)  Ngöôøi duøng khoâng ñoùng vai troø naøo trong phaân tích vaø thieát keá heä thoáng 
(c)  Moät baûng quyeát ñònh laø moät bieåu dieãn baèng hình aûnh doøng döõ lieäu 
(d)  MuÏc ñích söû duïng duy nhaát cuûa löôïc ñoà doøng döõ lieäu laø caùc tö lieäu 
(e)  Löôïc ñoà doøng döõ lieäu nhaán maïnh doøng logic cuûa döõ lieäu choáng laïi doøng vaät lyù 

cuûa döõ lieäu 

(f)  Caùc ñaàu ra (outputs) cuûa maùy tính coù theå ñöôïc thieát keá theo aûnh höôûng mang 

tính con ngöôøi 

(g)  Caùc kyõ thuaät laäp trình coù caáu truùc khoâng coù moät vò trí naøo trong thieát keá chöông 

trình höôùng ñoái töôïng. 

(h)  Moät prototype khoâng theå ñöôïc caûi tieán trong moät saûn phaåm cuoái 

 
 
 


Document Outline