BCVT Bài Giảng Lập Trình Hướng Đối Tượng (NXB Hồ Chí Minh 2002) Nguyễn Việt Cường, 384 Trang

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

v

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

2


































background image

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

3

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

4

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

4

Function

5

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

5

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

C

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

6

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

7


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

8


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

9

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

s

Freeing

s

Hello
Freeing

s

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

1

Received

1

Destructing

1

Destructing

1


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

1

Received

1

Destructing

1


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 : public, private 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 members) cuû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 B1, public 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 motorized, public 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 istream, ostream 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


2

1.4142

4

3

1.7321

9

4

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øn, toaù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 ifstream, ofstream 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õ

0

Archive

File bình thöôøng : ghi / ñoïc (maëc ñònh)

1

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 >> i >> f >> 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 StackType> StackType 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ù : try, catch, throw .

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

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

Y


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

A

Process

B



Process

C

Process

D

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

A

C

A

D

A

B1

B

B2

B


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.

A

B X Y

C

D

E

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

Z


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

1

Data

Function

2

Object



A


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

1

Task

2

Task

3

Exit

(a)

Sequence

Entry

True

False

Test

Task

1

Task

2


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


Wyszukiwarka

Podobne podstrony:
Giáo Trình Ngôn Ngữ Lập Trình C (NXB Hồ Chí Minh 2007) Nguyễn Hữu Tuấn, 143 Trang
Nhập Môn Hệ Điều Hành Linux (NXB Hồ Chí Minh 2001) Trịnh Ngọc Minh, 38 Trang
ĐHQG Nhập Môn Hệ Điều Hành Linux (NXB Hồ Chí Minh 2001) Trịnh Ngọc Minh, 38 Trang
ĐHBK Bài Giảng Hệ Điều Hành (NXB Hà Nội 2001) Lê Tiến Dũng, 96 Trang
ĐHHH Bài Giảng Hệ Điều Hành Mã Nguồn Mở (NXB Hải Phòng 2010) Ngô Quốc Vinh, 93 Trang
ĐHĐL Giáo Trình Kỹ Thuật Lập Trình Nâng Cao (NXB Đà Lạt 2002) Trần Hoàng Thọ, 108 Trang
Bài Giảng Quang Điện Tử Và Quang Điện Ts Nguyễn Văn Cường, 56 Trang
Hướng Dẫn Lập Và Quản Lý Chi Phí Đầu Tư Xây Dựng Công Trình Bộ Xây Dựng, 46 Trang
Giám Sát Thi Công Và Nghiệm Thu Lắp Đặt Thiết Bị Trong Công Trình Dân Dụng (NXB Hà Nội 2002) Lê Kiề
Slide Lập Trình Trên Môi Trường Windows Với ADO NET Phạm Minh Tuấn, 23 Trang
Slide Lập Trình Trên Môi Trường Windows Với Windows Form Phạm Minh Tuấn, 34 Trang
ĐHBK Tài Liệu Hướng Dẫn Thiết Kế Thiết Bị Điện Tử Công Suất Trần Văn Thịnh, 122 Trang
BCVT Bài Tập Tiếng Anh Chuyên Ngành Điện Từ Viễn Thông Ths Nguyễn Quỳnh Giao, 86 Trang
ĐHMO Lập Dự Toán Xây Dựng Cơ Bản Ths Lương Văn Cảnh, 21 Trang
ĐHĐL Giáo Trình Kỹ Thuật Lập Trình Pascal (NXB Đà Lạt 2001) Nguyễn Danh Hưng, 135 Trang
Giáo Trình Lập Trình Pascal Căn Bản Nhiều Tác Giả, 90 Trang
Lập Trình Web Động Với PHP và MySQL Phần 1 Tống Phước Khải, 132 Trang
7BANK04, W ka˙dym kraju istnieje okre˙lony ustr˙j pieni˙˙ny. Emisja znak˙w pieni˙˙nych b˙d˙cych praw

więcej podobnych podstron