Yeâu caàu: Xaây döïng moät öùng duïng tin hoïc ñeå phuïc vuï cho coâng ty vaø cho caùc ñaïi lyù, giöõa ñaïi lyù vaø coâng ty ñöôïc noái qua modem ñeå chuyeån baùo caùo, öùng duïng phaûi chuù yù ñeán yeáu toá nhieàu soá lieäu caàn ñöôïc löu tröõ. Baùo caùo trình baøy: Moâ hình quan nieäm vaø xöû lyù, thuyeát minh caáu truùc vaät lyù ñaõ caøi ñaët, moâ taû thieát keá giao dieän, caøi ñaët theo caáu truùc ClientServer. Thöïc hieän: ÖÙng duïng tin hoïc goàm 2 phaân heä: coâng ty vaø ñaïi lyù Beân coâng ty löu tröõ moät cô sôû döõ lieäu goàm taát caû thoâng tin caàn thieát. Beân ñaïi lyù löu tröõ cô sôû döõ lieäu goàm: Caùc chuûng loaïi haøng, soá löôïng haøng nhaän, thoâng tin baùn haøng, thoâng tin veà caùc ñôït khuyeán maõi. Nhöõng thoâng tin naøo thuoäc Coâng ty thì seõ do Coâng ty chuyeån ñeán Ñaïi lyù, Ñaïi lyù chæ söû duïng, khoâng ñöôïc pheùp söûa ñoåi. Thöïc hieän nghieäp vuï: haøng tuaàn laäp phieáu yeâu caàu caùc maët haøng cho coâng ty vaø chuyeån döõ lieäu naøy cho coâng ty, cuoái tuaàn laäp baùo caùo soá löôïng haøng ñaõ baùn trong tuaàn trong moãi chuûng loaïi, cuoái thaùng thanh toaùn tieàn cho coâng ty. II. MOÂ HÌNH QUAN NIEÄM DÖÕ LIEÄU 1. PHAÂN TÍCH BAØI TOAÙN Phaân tích caùc söï kieän coù trong ñeà baøi vaø moät soá giaû thieát ñöôïc ñöa theâm vaøo döôùi ñaây: Ñaïi lyù: Chöùa ñöïng thoâng tin veà caùc ñaïi lyù cuûa coâng ty. Phieáu yeâu caàu: Giuùp coâng ty xaùc ñònh löôïng haøng caàn cung öùng cho ñaïi lyù. Moái quan heä Phieáu yeâu caàu – Maët haøng theå hieän thoâng tin caùc maët haøng cuøng vôùi soá löôïng yeâu caàu (Chi tieát yeâu caàu). Phieáu yeâu caàu phaùt sinh haøng tuaàn töø ñaïi lyù, suy ra coù moät moái quan heä giöõa Phieáu yeâu caàu vaø yeáu toá thôøi gian ñöôïc ghi nhaän (tuaàn). Maët haøng: Vôùi caùc thuoäc tính: maõ haøng, teân haøng, quy caùch, ñôn giaù. Ñôn giaù naøy do coâng ty aán ñònh tröôùc cho ñaïi lyù, ñôn giaù naøy coù theå thay ñoåi neáu maët haøng trong thôøi kyø khuyeán maõi, hoaëc bieán ñoäng theo thò tröôøng taïi töøng thôøi ñieåm. Giaû thieát trong baøi toaùn naøy ñôn giaù naøy oån ñònh trong moät thôøi gian daøi, coøn thöïc teá thì ñôn giaù naøy coù theå seõ gaén cuøng vôùi moät giaù trò thôøi gian xaùc ñònh. Moät ñaïi lyù thuoäc moät ñòa baøn xaùc ñònh, vaø ñôït khuyeán maõi thì aùp duïng ñoàng loaït cho caùc ñaïi lyù treân cuøng moät ñòa baøn. Ta coù moái keát hôïp Ñaïi lyù – Ñòa baøn, vaø neáu bieát ñaïi lyù thuoäc ñòa baøn thì maëc nhieân bieát ñöôïc ñôït khuyeán maõi treân ñòa baøn ñoù laø coù hieäu löïc aùp duïng cho ñaïi lyù. Moái keát hôïp giöõa Ñôït khuyeán maõi – Maët haøng dieãn taû moät danh saùch caùc maët haøng, giaù khuyeán maõi cuûa maët haøng ñoù trong moät ñôït khuyeán maõi. Khuyeán maõi: Hình thöùc khuyeán maõi thoâng thöôøng laø giaûm giaù, giaù naøy ta goïi laø ÑôngiaùKM. Ví duï neáu giaûm cho 1000 ñôn vò haøng ñaàu tieân keå töø ngaøy A thì 1000 goïi laø SoLuongKM. Hình thöùc khuyeán maõi mua haøng taëng haøng (5 taëng 1, …), giaû söû coâng ty gôûi ñaïi lyù 500 chai nöôùc xaû thôm ñeå taëng khaùch haøng thì 500 chai naøy coâng ty seõ khoâng tính vaøo soá löôïng haøng xuaát (cho moät phieáu yeâu caàu baát kyø) cho ñaïi lyù. Thoâng tin baùn haøng trong tuaàn: Soá löôïng moãi loaïi haøng baùn taïi ñaïi lyù laø con soá toång keát cuoái cuøng, ôû ñaây ta khoâng chuù yù ñeán chi tieát töøng moùn haøng ñaõ ñöôïc baùn cuï theå cho ai, baùn coù hoaù ñôn khoâng hay khoâng. Thöù hai haøng tuaàn caùc ñaïi lyù phaûi baùo caùo veà coâng ty soá löôïng ñaõ baùn ñöôïc trong tuaàn qua trong moãi chuûng loaïi, töø ñoù coâng ty suy ra ñöôïc soá toàn taïi ñaïi lyù. Thoâng tin baùn haøng phuï thuoäc moãi ñaïi lyù cuï theå, ñoàng thôøi phuï thuoäc vaøo töøng tuaàn, moái keát hôïp Tuaàn – Maët haøng – Ñaïi lyù theå hieän thoâng tin baùn haøng trong tuaàn cuûa ñaïi lyù. Haøng tuaàn ñaïi lyù göûi phieáu yeâu caàu trong ñoù ghi roõ loaïi haøng, soá löôïng cho coâng ty, ta coù moái keát hôïp Tuaàn Phieáu yeâu caàu. Coâng ty yeâu caàu caùc ñaïi lyù thanh toaùn tieàn moät laàn vaøo cuoái moãi thaùng, Ñoù laø soá tieàn töông öùng soá haøng thöïc baùn trong thaùng (4 tuaàn) coäng laïi. Nhö vaäy coù moái keát hôïp giöõa ñaïi lyù vaø thôøi gian (Thaùng) veà xaùc laäp thôøi haïn, soá tieàn thanh toaùn. Chuùng ta ñeà nghò moâ hình quan nieäm cho Heä thoáng thoâng tin (HTTT) Quaûn lyù phaân phoái haøng hoùa cho caùc ñaïi lyù cuûa moät doanh nghieäp nhö sau: 2. MOÂ HÌNH QUAN NIEÄM DÖÕ LIEÄU (ERD) Heä thoáng thoâng tin: QUAÛN LYÙ PHAÂN PHOÁI HAØNG HOÙA CHO CAÙC ÑAÏI LYÙ MOÂ HÌNH QUAN NIEÄM DÖÕ LIEÄU Ngaøy laäp: 01012003
Trang 1Lời cảm ơn
Trớc tiên, tôi xin bày tỏ lòng biết ơn sâu sắc tới thầy giáo ớng dẫn TS Đoàn Văn Ban, phòng CSDL< Viện Công Nghệ Thông Tin thuộc trung tâm Khoa Học Tự Nhiên và Công Nghệ Quốc Gia đã tận tình giúp đỡ tôi hoàn thành bài luận văn này.
h-Tôi xin chân thành cảm ơn các thầy, cô giáo khoa Công Nghệ Thông Tin trờng ĐHDL Đông Đô đã giảng dạy và giúp đỡ
em trong quá trình học tập ở trờng
Cuối cùng, xin chân thành cảm ơn những ngời thân trong gia
đình và bạn bè đã giúp đỡ, động viên trong quá trình học tập
Trang 2I.4 Các lớp đối tợng 7
I.5 Trừu tợng hoá dữ liệu và bao gói thông tin 8
I.6 Thừa kế 8
I.7 Tơng ứng bội 9
I.8 Truyền thông báo 10
I.9 Những ứng dụng của lập trình hớng đối tợng 11
Chơng II Thiết kế và cài đặt các lớp đối tợng II.1 Định nghĩa lớp 13
II.1.1 Khai báo lớp tên đối tợng 13
II.1.2 Tạo lập các lớp đối tợng 14
II.1.3 Các thành phần dữ liệu 15
II.2 Tính tơng ứng bội 16
II.2.1 Hàm tải bội 17
II.2.2 Chuyển đổi kiểu 21
II.3 Kế thừa và sự mở rộng các lớp 22
II.3.1 Kế thừa đơn 23
II.3.2 Kế thừa đa mức 27
II.3.3 Kế thừa phân cấp 28
II.3.4 Kế thừa bội 28
II.3.5 Kế thừa kép 29
II.3.6 Các lớp cơ sở ảo 29
II.3.7 Cấu tử trong các lớp dẫn xuất 30
II.3.8 Hàm ảo 32
Chơng III Hàm và lớp mẫu III.1 Hàm mẫu 34
III.1.1 Định nghĩa 34
III.1.2 Hàm mẫu có nhiều tham số hình thức 35
III.1.3 Hàm mẫu có nhiều tham số khác nhau 36
III.2 Lớp mẫu 38
III.2.1 Định nghĩa 38
Trang 3III.2.2 Lớp mẫu có tham số 39
III.3 Kết luận 39
Chơng IV Cấu trúc dữ liệu và các lớp mẫu IV Cấu trúc dữ liệu 40
IV.1.1 Lớp chứa 41
IV.1.2 Lớp chứa thần ảo 41
IV.2.1 Ngăn xếp 42
IV.2.2 Lu trữ ngăn xếp bằng mảng 42
IV.2.3 Xây dựng lớp ngăn xếp mẫu 43
IV.3.1 Hàm đợi 44
IV.3.2 Xây dựng lớp hàm đợi mẫu 45
IV.4 Hàng quay tròn 47
IV.5 Danh sách liên kết 48
IV.6 Danh sách liên kết đơn 48
IV.7 Danh sách liên kết đôi 56
IV.8 Cây nhị phân 64
IV.9 Nhận xét 74
Phần B I Chơng trình quản lý sinh viên 76
II Chơng trình thống kê từ tiếng Việt 85
Kết luận 92
Tài liệu tham khảo 93
Trang 4Chơng I
I.1 Lập trình hớng đối tợng là gì?
Lập trình hớng đối tợng dựa trên nền tảng là các đối tợng Đối tợng
đợc xây dựng trên cơ sở gắn cấu trúc dữ liệu với các phép toán sẽ thể đợc
đúng cách mà chúng ta suy nghĩ, bao quát về thế giới thực [3]
Lập trình hớng đối tợng cho phép chúng ta kết hợp những tri thứcbao quát về các quá trình với những khái niệm trừu tợng đợc sử dụng trongmáy tính
Lập trình hớng đối tợng là phơng pháp lập trình lấy đối tợng làm nềntảng để xây dựng thuật giải, xây dựng chơng trình, là cách tiếp cận để phânchia chơng trình thành các đơn thể (modul) bằng cách tạo ra các vùng bộnhớ cho cả dữ liệu lẫn hàm và chúng sẽ đợc sử dụng nh các mẫu để tạo rabản sao từng đơn thể khi cần thiết Đối tợng ở đây đợc xem nh là vùng phânchia chia bộ nhớ trong máy tính để lu trữ dữ liệu và tập các hàm tác độngtrên dữ liệu gắn với chúng
Khái niệm “Hớng đối tợng” đợc xây dựng trên nền tảng của kháiniệm “Lập trình có cấu trúc“ và ”Sự trừu tợng hoá dữ liệu” sự thay đổi căn
Trang 5bản là ở chỗ một chơng trình hớng đối tợng đợc thiết kế xoay quanh các dữliệu mà ta làm việc trên nó, hơn là theo bản thân chức năng của chơng trình.
Lập trình hớng đối tợng đặt trọng tâm vào đối tợng, yếu tố quantrọng trong quá trình phát triển chơng trình và nó không cho phép dữ liệuchuyển động tự do trong hệ thống Dữ liệu đợc gắn chặt với từng hàm thànhcác vùng riêng mà các hàm đó tác động lên và nó đợc bảo vệ cấm các hàmngoại lai truy nhập tuỳ tiện Tuy nhiên các đối tợng có thể trao đổi thông tinvới nhau thông qua việc trao đổi thông báo.[5]
Tóm lại, so sánh lập trình cấu trúc lấy chơng trình con làm nền tảng:
Trong lập trình hớng đối tợng chúng ta có :
Lập trình hớng đối tợng có những đặc tính chủ yếu sau:
Tập trung vào dữ liệu thay cho các hàm
Chơng trình đợc chia thành tập các lớp đối tợng
Cấu trúc dữ liệu đợc thiết kế sao cho đặc tả các đối tợng
Các hàm đợc xác định trên các vùng dữ kiệu của đối tợng đợc gắnvới nhau trên cấu trúc của dữ liệu đó
Dữ liệu đợc bao bọc, che dấu và không cho phép các hàm ngoạilai truy nhập tự do
Các đối tợng trao đổi thông tin với nhau qua các hàm
Dữ liệu và các hàm mới có thể dễ dàng bổ xung vào đối tợng nào
đó khi cần thiết
Chơng trình đợc thiết kế theo cách tiếp cận bottom-up
I.2 Các u điểm của lập trình hớng đối tợng
Chơng trình = Cấu trúc dữ liệu + Giải Thuật
Đối tợng =Dữ Liệu + Hành vi của dữ liệu
Trang 6 Thông qua nguyên lý thừa kế, chúng ta có thể loại bỏ đợc những
đoạn chơng trình lặp lại, d thừa trong quá trình mô tả các lớp và khảnăng sử dụng các lớp đã đợc xây dựng
Chơng trình đợc xây dựng từ các đơn thể (module) trao đổi với nhaunên việc thiết kế và lập trình sẽ đợc thực hiện theo quy trình nhất
định chứ không phải dựa vào kinh nghiệm và kỹ thuật nh trớc Điềunày đảm bảo rút ngắn đợc thời gian xây dựng hệ thống và tăng năngxuất lao động
Nguyên lý che dấu thông tin giúp ngời lập trình tạo ra đợc những
ch-ơng trình an toàn không bị thay đổi bởi những chch-ơng trình khác
Có thể xây dựng đợc các ánh xạ đối tợng của bài toán vào đối tợngcủa chơng trình
Cách tiếp cận thiết kế đặt trọng tâm vào dữ liệu giúp ta xây dựng đợcmô hình chi tiết và gần với dạng cài đặt hơn
Những hệ thống hớng đối tợng dễ mở rộng, nâng cấp thành những hệthống lớn hơn
Kỹ thuật truyền thông báo trong việc tao trao đổi thông tin giữa các
đối tợng giúp cho việc mô tả giao diện với các hệ thống bên ngoài
t-Một đối tợng có thể đợc minh hoạ nh sau :
Đối T ợng
Thuộc TínhHàm
Trang 7Hình 1 Cấu trúc tổng quát của một đối tợng.
Chẳng hạn chúng ta xét đối tợng hình chữ nhật bao gồm các thuộc tính(x1,y1) toạ độ góc trên bên trái, d, r là chiều dài chiều rộng của hình chữnhật Các hàm: nhập số liệu cho hình chữ nhật, hàm tính diện tích, chu vi vàhàm hiển thị Nh vậy đối tợng hình chữ nhật có thể đợc mô tả nh sau:
I.4 Các lớp đối tợng
Một tập dữ liệu và các hàm của một tập đối tợng có thể đợc xem nhmột kiểu dữ liệu đợc định nghĩa bởi ngời sử dụng Kiểu dữ liệu ở đây đợcgọi là lớp (class), đó là một tập các thuộc tính và các hàm mô tả thế giớithực, một đối tợng là thể hiện của một lớp Lớp là khái niệm trung tâm củalập trình hớng đối tợng, nó là sự mở rộng cấu trúc (struct) của C và bản ghi(record) của Pascal Trong lập trình hớng đối tợng, lớp hầu nh đồng nhất vớikiểu dữ liệu trừu tợng Lớp là khái niệm tĩnh, có thể nhận biết ngay từ vănbản chơng trình Ngợc lại đối tợng là khái niệm động, nó đợc xác địnhtrong bộ nhớ của máy tính nơi đối tợng chiếm một vùng của bộ nhớ lúcthực hiện chơng trình Đối tợng đợc tạo ra để xử lý thông tin, thực hiệnnhiệm vụ đợc thiết kế và sau đó bị huỷ bỏ khi đối tợng đó hết vai trò Khimột lớp đợc định nghĩa, thì nó có thể tạo ra số lợng các đối tợng tuỳ ý củalớp đó Nh vậy lớp là tập hợp các đối tợng cùng kiểu Sự khác biệt giữa lớp
và đối tợng cũng giống nh sự khác biệt giữa tập hợp các phần tử và mộtphần tử trong tập hợp.[5]
Hình 2 Mô tả đối t ợng hình chữ nhật
Trang 8I.5 Trừu tợng hoá dữ liệu và bao gói thông tin
Việc đóng gói dữ liệu và các hàm vào một đơn vị cấu trúc đợc xem
nh một nguyên tắc (che dấu) thông tin, dữ đợc tổ chức sao cho thế giới bênngoài không truy nhập đợc vào mà chỉ cho phép các hàm trong cùng lớphoặc trong những lớp có quan hệ thừa với nhau đợc quền truy nhập Chínhcác hàm thành phần của lớp sẽ đóng vai trò nh là giao diện giữa dữ liệu của
đối tợng và phần còn lại của chơng trình Nguyên tắc bao gói dữ liệu đểngăn cấm sự truy nhập trực tiếp trong lập trình đợc gọi là che dấu thông tin
Trừu tợng hoá là cách biểu diễn những đặc tính chính và bỏ qua
những chi tiết vụn vặt hoặc những giải thích Để xây dựng các lớp chúng taphải sử dụng khái niệm trừu tợng hoá Trong lập trình hớng đối tợng lớp đ-
ợc sử dụng nh dữ liệu trừu tợng Ví dụ nh chúng ta có thể định nghĩa mộtlớp là danh sách các thuộc tính trừu tợng nh là kích thớc, hình dáng mầu vàcác hàm xác định trên các thuộc tính này để mô tả các đối tợng trong khônggian hình học
I.6 Thừa Kế
Thừa kế là quá trình trong đó các đối tợng của lớp này đợc quyền sửdụng một số tính chất của các đối tợng của các lớp khác
Nguyên lý thừa kế hỗ trợ cho việc tạo ra cấu trúc phân cấp các lớp
Nó đợc thực hiện dựa trên nguyên lý tổng quát hoá hoặc chi tiết hoá các đặctính của các đối tợng trong các lớp
Trong lập trình hớng đối tợng, khái niệm thừa kế kéo theo ý tởng sửdụng lại Nghĩa là một lớp đã đợc xây dựng (lớp cha hay lớp cơ sở) củachúng có thể bổ sung thêm các tính chất mới để tạo các lớp mới (lớp conhay lớp dẫn xuất) mô tả chi tiết hơn về một nhóm đối tợng cụ thể (theonguyên lý chi tiết hoá) hoặc từ một nhóm lớp có số đặc tính giống nhau gộpchung các đặc tính đó lại để tạo ra một lớp mới, đợc gọi là lớp trừu tợng(nguyên lý tổng quát hoá)
Trang 9Khái niệm kế thừa đợc hiểu nh cơ chế sao chép ảo không đơn điệu.Trong thực tế, mọi việc xảy ra tựa nh những lớp cơ sở đều đợc sao vào tronglớp dẫn xuất mặc dù điều này không đợc cài đặt tờng minh (gọi là sao chép
ảo) và việc sao chép chỉ đợc xác định trong lớp cơ sở (sao chép không đơn
điệu)
Một lớp có thể kế thừa các tính chất của một hay nhiều lớp cơ sở ởcác mức khác nhau, do đó có năm dạng kế thừa đợc sử dụng trong lập trìnhhớng đối tợng là: kế thừa đơn, kế thừa bội, kế thừa phân cấp, kế thừa đamức và kế thừa phức hợp (chơng sau sẽ nói rõ về các dạng kế thừa này).[3]
I.7 Tơng ứng bội
Tơng ứng bội là một khái niệm có khả năng nh các phép toán có thể
đợc thực hiện ở nhiều dạng khác nhau Hành vi của các phép toán tơng ứngbội phụ thuộc vào kiểu dữ liệu mà nó sử dụng để xử lý Tơng ứng bội đóngvai trò quan trọng trong việc tạo ra các đối tợng có cấu trúc bên trong khácnhau nhng có khả năng dùng chung một giao diện bên ngoài (nh tên gọi)
Điều này có nghĩa là một lớp các phép toán đợc định nghĩa theo nhữngthuật toán khác nhau, nhng có khả năng sử dụng theo cùng một cách giốngnhau.Tơng ứng bội là sự mở rộng khái niệm sử dụng lại trong nguyên lý kếthừa Liên kết động là dạng liên kết các hàm, thủ tục khi chơng trình thựchiện các lời gọi tới các hàm, thủ tục đó Nh vậy, trong liên kết động nộidung của đoạn chơng trình ứng với thủ tục, hàm cho đến khi thực hiện cáclời gọi tới các thủ tục và hàm đó Nó cho phép chúng ta can thiệp vào sựhoạt động của các thực thể mà không cần biên dịch lại toàn bộ chơng trình,chúng ta có thể truyền và nhận thông tin từ các đối tợng mới này giống nhcác đối tợng đã có Liên kết động liên quan chặt chẽ tới tơng ứng bội và kế
thừa, đôi khi liên kết động còn gọi là liên kết trễ hay liên kết vào lúc chạy
(vì các phơng thức chỉ đợc gọi vào lúc chơng trình biên dịch chơng trìnhbiên dịch ra ngôn ngữ máy).[3]
Chẳng hạn nh hàm VE() trong hình 3, theo nguyên lý kế thừa thì mọi
đối tợng đều có thể sử dụng hàm này để vẽ theo yêu cầu Tuy nhiên, thuậttoán thực hiện hàm VE() là duy nhất đối với từng đối tợng Hình_TRòn,
Đa_Giác, Đơng_th và vì vậy hàm VE() sẽ đợc định nghĩa lại khi các
đối tợng tơng ứng đợc xác định
Trang 10I.8 Truyền thông báo
Các đối tợng gửi và nhận thông tin với nhau giống nh con ngời trao
đổi thông tin với nhau Chính nguyên lý trao đổi thông tin với nhau bằngcách truyền thông báo cho phép chúng ta dễ dàng xây dựng đợc hệ thốngmô phỏng gần những hệ thống trong thế giới thực Truyền thông báo chomột đối tợng tức là báo cho nó phải thực hiện một việc gì đó Cách ứng xửcả đối tợng sẽ đợc mô tả ở trong lớp thông qua các hàm (hay còn đợc gọi làlớp dịch vụ) Thông báo truyền đi phải chỉ ra đợc hàm cần thực hiện trong
đối tợng nhận thông báo Hơn thế nữa thông báo truyền đi phải xác định tên
đối tợng, tên hàm và thông tin truyền đi
Ví dụ: Lớp CONG_NHAN có thể là đối tợng cụ thể đợc xác định bởiHO_TEN nhận đợc thông báo cần TINH_LUONG đã đợc xác định tronglớp CONG_NHAN Thông báo đó sẽ đợc xử lý nh sau:
Mỗi đối tợng chỉ tồn tại trong một thời gian nhất định Đối tợng tạo
ra khi nó đợc khai báo và sẽ bị huỷ bỏ khi chơng trình ra khỏi miền xác
định của đối tợng đó Sự trao đổi thông tin chỉ có thể thực hiện trong thờigian đối tợng tồn tại
đối t ợng thông báo thông tinCONG_NHAN.TINH_LUONG(HO_TEN)
Hình HọcVE()
ĐA_GIACVE(ĐA_GIAC)
ĐƯƠNG_THVE(ĐƯƠNG_TH)
Trang 11I.9 Những ứng dụng của lập trình hớng đối tợng
Lập trình hớng đối tợng là một trong những thuật ngữ đợc nhắc đếnnhiều nhất trong công nghệ phần mềm và nó đợc ứng dụng để phát triểnphần mềm và nhiều lĩnh vực khác nhau Trong số đó có ứng dụng quantrọng và nổi tiếng nhất hiện nay là lĩnh vực thiết kế giao diện với ngời sửdụng Ví dụ nh Windows, hàng trăm hệ thống với giao diện Windows đã d-
ợc phát triển dựa trên kỹ thuật lập trình hớng đối tợng Những hệ thông tindoanh nghiệp trong thực tế rất phức tạp, chứa nhiều đối tợng, các thuộc tính
và hàm Để giải quyết những hệ thống phức hợp nh thế thì lập trình hớng
đối tợng lại tỏ ra khá hiệu quả Tóm lại những lĩnh vực ứng dụng của kỹthuật lập trình hớng đối tợng bao gồm:
Những hệ thông tin làm việc theo thời gian thực
Trong lĩnh vực mô hình hoá hoặc mô phỏng quá trình
Các cơ sở dữ liệu hớng đối tợng
Hệ siêu văn bản và đa phơng tiện
Lĩnh vực trí tuệ nhân tạo và các hệ chuyên gia
Lập trình song song và các mạng nơ_ron
Những hệ tự động hoá văn phòng và trợ giúp quyết định
Những hệ CAD/CAM
Với nhiều đặc tính của lập trình hớng đối tợng nói riêng, cả phơngpháp phát triển hớng đối tợng nói chung, chúng ta hy vọng nền công nghiệpphần mềm sẽ cải tiến không những về chất lợng mà còn gia tăng nhanh về
số lợng trong tơng lai Kỹ nghệ hớng đối tợng sẽ là thay đổi cách suy nghĩ
và cách thực hiện quá tình phân tích, thiết kế và cài đặt các hệ thống, gópphần giải quyết những vấn đề tồn tại trong công nghệ phần mềm
C++ là một công cụ lập trình hớng đối tợng
C++ là công cụ lập trình hớng đối tợng Ban đầu đợc gọi là "C with class" (Cvới các lớp) sau đó C++ đợc phát triển vào những năm đầu thập kỉ 80 ởAT&T Bell Laboratories Nó đợc phát triển trên nền ngôn ngữ C
Trang 12C++ là một tập mở rộng của C, vì thế hầu hết các tính chất của C vẫn đợc sửdụng trong C++ Điều này có nghĩa là hầu nh toàn bộ các chơng trình đợcviết bằng C thì cũng là chơng trình của C++ Tuy nhiên cũng có một số khácbiệt làm cho chơng trình C không thực đợc dới chơng trình C++.
Ba khái niệm quan trọng của C++ đợc bổ xung vào C là: lớp, hàm tảibội và toán tử tải bội Những khái niệm cho phép chúng ta tạo ra nhữngkiểu dữ liệu trừu tợng, kế thừa nhiều tính chất của những kiểu dữ liệu đãxây dựng và hỗ trợ cho việc sử dụng cơ chế tơng ứng bội cho C++ trở thànhngôn ngữ hớng đối tợng thực sự Các đặc tính của C++ cho phép ngời lậptrình dễ dàng xây dựng đợc các chơng trình lớn, có tính mở, dễ thích nghi,công việc bảo trì ít tốn kém hơn C++ là công cụ thích ứng cho vệc xây dựngcác chơng trình lớn nh các hệ soạn thảo chơng, trình dịch, các hệ cơ sở dữliệu, những hệ thống truyền tin và nhiều ứng dụng phức tạp khác
C++ hỗ trợ cho việc tạo ra cấu trúc phân cấp các đối tợng giúp chúng
ta có thể xây dựng những th viện các đối tợng để cho nhiều ngời lập sửdụng đợc Do C++ là ngôn ngữ lập trình hớng đối tợng nên tất nhiên nó sẽ
có những gì mà "hớng đối tợng" có
Trang 13ChƯơng ii
II.1 Định nghĩa lớp
II.1.1 Khai báo lớp tên đối tợng
Khai báo lớp là mô tả kiểu và nhiều miền xác định các thành phầncủa lớp, khai báo lớp cũng nh khai báo các kiểu dữ liệu quen thuộc khác, nó
là public sẽ là private
Trang 14Những biến đợc khai báo trong các lớp đợc gọi là dữ liệu thành phần,còn các hàm đợc gọi là hàm thành phần Các hàm thành phần kiểu privatechỉ có thể truy nhập đợc các dữ liệu và hàm trong vùng private, còn cáchàm thành phầm kiểu public thì truy nhập đợc tất cả các kiểu dữ liệu và cáchàm trong cùng lớp.
Trong lớp Point thì các biến đợc khai báo trong vùng private (vùngriêng) là dữ liệu thành phần, còn các hàm trong vùng public (vùng chung) làcác thành phần Dữ liệu thành phần của lớp không thể có kiểu của chính lớp
đó, nhng có thể là kiểu con trỏ của lớp này, ví dụ:
II.1.2 Tạo lập các đối tợng
Trong C++, một đối tợng là một phần tử dữ liệu đợc khai báo kiểu làmột class Trong ví dụ trên, khai báo lớp Point mới chỉ xác định các thànhphần của lớp Point chứ cha tạo ra một đối tợng cụ thể Lớp là một kiểu đốitợng trừu tợng, nên sau khi định nghĩa lớp chúng ta có thể khai báo cácbiến giống nh đối với kiểu đợc định nghĩa bởi ngời sử dụng
Trang 15Khi các đối tợng đợc tạo lập thì sẽ có một chùm bộ nhớ đợc cấp phát
để chứa các thành phần dữ liệu của mỗi đối tợng Các đối tợng của cùngmột lớp có thể đợc khởi đầu và gán cho một đối tợng khác theo ngầm định,việc sao một đối tợng là tơng đơng với việc sao một thành phần của nó
Các đối tợng còn có thể đợc cấp phát động trong heap, giống nhnhững phần tử khác
II.1.3 Các thành phần dữ liệu
Các thành phần dữ liệu trong một lớp không thể đợc khai báo kiểuauto, register, hay extern Chúng có thể là các enum, nhóm bit và các kiểudữ liệu có sẵn hoặc của ngời sử dụng định nghĩa Thành phần dữ liệu cũng
có thể là một đối tợng, tuy nhiên chúng chỉ có thể là những đối tợng của cáclớp đã đợc khai báo hoặc đã đợc định nghĩa trớc đó
*Dữ liệu thành phần kiểu private
Khi các thành phần dữ liệu một lớp đợc khai báo theo kiểu private thìchỉ có thánh phần của chính lớp đó hoặc các lớp bạn của nó mới đợc truynhập đến các thành phần này
*Dữ liệu thành phần public
Nếu ta khai báo lại các thành phần dữ liệu trong lớp Point sang dạngpublic, tức là: Lúc đó mội thành phần trong lớp Point đều có thể đợc truynhập từ thế giới bên ngoài
*Dữ liệu thành phần protected
Để sử dụng đợc các thành phần dữ liệu của một lớp từ các lớp khácnhng phải bảo đảm nguyên lý che dấu thông tin thì chúng ta phải khai báokiểu protected Các thành phần dữ liệu trong protected chỉ cho phép cácthành phần trong cùng lớp và trong dẫn xuất truy nhập đến
*Dữ liệu thành phần tĩnh static
Dữ liệu thành phần tĩnh là dữ liệu đợc khai báo với từ khoá static ở
đầu Khi dữ liệu thành phần tĩnh thì tất cả các thể hiện của lớp đó đều đợcphép dùng chung thành phần dữ liệu này Dữ liệu theo kiểu static đợc phân
bố ở một vùng bộ nhớ cố định trong quá trình liên kết cũng giống nh cácbiến đợc khai báo theo kiểu tổng thể (global)
Trang 16Biến dữ liệu tĩnh có những tính chất sau:
Khi đối tợng đầu tiên của lớp đợc tạo lập thì các biến dữ liệu tĩnh
đợc gán là 0
Chỉ có một bản sao của biến tĩnh đợc tạo ra cho cả lớp và sẽ đợc
sử dụng chung cho tất cả các đối tợng trong cùng lớp
Chỉ đợc sử dụng trong lớp, nhng nó tồn tại trong suốt thời gianhoạt động của chơng trình
II.2 Tính tơng ứng bội
Nh trên đã nói tơng ứng bội là khả năng sử dụng một tên gọi dớinhiều dạng khác nhau Hàm và toán tử tải bội là hai trờng hợp điển hình củatơng ứng bội Hàm, toán tử tải bội sẽ đợc phân tích để đối sánh về kiểu, sốlợng tham biến trong thời gian dịch để chọn ra hàm, toán tử tơng ứng Liênkết đợc thực hiện trong thời gian biên dịch đợc gọi là thời gian tĩnh
Thế mạnh của tơng ứng bội có hai cấp:
Cho phép chúng ta xử lý các khái niệm có liên hệ nhau theo mộtcách giống nhau, làm cho chơng trính tổng quát hơn và dễ hiểuhơn
Tính tơng ứng bội có thể đợc dùng để viết chơng trình có thể mởrộng nhiều hơn Khi một loại mới đợc thêm vào có liên hệ với cáckiểu đang có thì bản chất tơng ứng bội của nó sẽ làm cho loại mớinày thích hợp ngay vào hệ thống mà không đòi hỏi phải thay phầncòn lại của chơng trình
Cơ chế thực hiện tơng ứng bội:T ơng ứng bội
T ơng ứng bội trong
thời gian dịch T ơng ứng bội trong thời gian thực hiện
Hàm ảoToán tử tải bội
Hàm tải bội
Trang 17II.2.1 Hàm tải bội
Ngôn ngữ C không cho phép ngời lập trình sử dụng cùng một tên chonhiều hàm trong một chơng trình Tuy vậy trong C++, việc định nghĩa này làhoàn toàn hợp lệ, các hàm này khác nhau về số lợng hoặc kiểu của các đối
số cho hàm Các hàm nh vậy đợc gọi là hàm tải bội (kể cả cấu từ)
II.2.2 Toán tử tải bội.
Đã nhiều lần chúng ta khẳng định rằng trong C++ chúng ta có thể tạo
ra những kiểu dữ liệu mới có hành vi giống nh các kiểu dữ liệu cơ sở Hơnthế nữa chúng ta còn có thể đa thêm định nghĩa mới cho những toán tử đợc
định nghĩa trớc Những toán tử cùng tên thức hiện đợc nhiều chức năng
khác nhau đợc gọi là toàn tử tải bội.
Quy tắc xây dựng toán tử tải bội:
1 Chỉ có thể xây dựng những toán tử đã có trong C++ để thành toán tửbội Không thể tự ý tạo ra những toán tử mới
2 Toán tử tải bội phải có ít nhất một toán hạng có kiểu là kiểu đợc
định nghĩa bởi ngời sử dụng
3 Chúng ta không thể tự ý làm thay đổi ý nghĩa cơ bản của toán tử
đã đợc định nghĩa trớc Ví dụ, chúng ta không thể định nghĩa lại
đợc các phép +, - đối với các kiểu cơ sở ( int, float)
4 Toán tử tải bội đợc xây dựng và sử dụng tuân theo quy tắc cú phápcủa toán tử cơ sở nh đã đợc định nghĩa trong ngôn ngữ
Trang 185 Một số toán tử không thể định nghĩa thành toán tử tải bội đợc( bảng 3-1).
6 Một số toán tử không thể sử sụng với friend để thành hàm toán tửtải bội( bảng 3-2), nhng có thể sử dụng hàm thành phần để đổithành hàm toán tử tải bội
7 Hàm thành phần toán tử tải bội một ngôi không có tham biến vàtrả lại giá trị tờng minh Hàm thân thiện toán tử tải bội một ngôi cótham biến là đối tợng
8 Hàm thành phần là toán tử tải bội hai ngôi có một tham biến vàhàm thân thiện là toán tử tải bội nhị nguyên có hai tham biến
9 Khi sử dụng hàm thành phần là toán tử tải bội nhị nguyên thì toánhạng bên trái của toán tử phải là đối tợng trong lớp chứa hàm thànhphần đó
10 Những toán tử số học nhị nguyên +, -, * Và / phải trả lại giá trịmột cách tờng minh
sizeof Toán tử xác định kích thớc
Toán tử xác định thành phần
.* Toán tử xác định thành phần mà con trỏ tới
:: Toán tử phân giải miền xác định
?: Toán tử điều kiện
Bảng 3-1 Những toán tử không thể tải bội
Trang 19Bảng 3-2 Những toán tử không sử dụng đợc với friend
Định nghĩa toán tử tải bội
Để đa thêm một chức năng mới cho toán tử, chúng ta phải biết đợc ýnghĩa của chức năng đó liên quan nh thế nào với các lớp mà toán tử đó sẽ đ-
ợc áp dụng
Định nghĩa tổng quát của toán tử tải bội là:
return-type class-name::operator op(arg-list)
{
-;// phần thân của các hàm toán tử
}
Trong đó return-type là kiểu của kết quả thực hiện các phép toán, op
là toán tử tải bội đứng sau là từ khoá operator op đợc gọi là hàm các toán tửvới các tham biến là arg-list
Hàm các toán tử tải bội phải là hàm thành phần (không phải là hàmtĩnh) hoặc là hàm thân thiện (friendly) Sự khác nhau cơ bản giữa chúng là:
Hàm thành phần tải bội không có đối số cho hàm toán tử một ngôi
và một đối số cho hàm toán tử hai ngôi
Hàm tải bội thân thiện có một đối số cho hàm toán tử một ngôi ,hai đối số cho hàm toán tử hai ngôi
Có sự khác nhau này bởi vì đối với hàm thành phần thì đối tợng đợc
sử dụng liên quan đến hàm thành phần đựơc tự động truyền vào tham sốcho nó còn hàm thân thiện thì không làm đợc điều đó
Trang 20openrator + (vector); // cộng vector, hàm thành phần
openrator - (vector & a); // trừ vector, hàm thành phần
openrator (const vector & a); // phép gán vector, hàm thành phần
openrator -(); // đổi dấu vector, hàm thành phần
friend vector+(vector, vector);// cộng vector hàm thân thiện
int oprator (vector);// so sánh hàm thành phần
friend int (vector, vector);// so sánh, hàm thân thiện
};
Trong đó các vector là lớp các đối tợng
Quá trình xác định các hàm toán tử tải bội đợc thực hiện nh sau:
Định nghĩa lớp để xác định kiểu dữ liệu sẽ đợc xác định trongphép toán tải bội
Khai báo hàm operator op trong vùng chung public của lớp Nó cóthể là hàm thành phần, hoặc là hàm thân thiện
Định nghĩa nội dung công việc cần thực hiện
Hàm thành phần op x (hoặc x op) sẽ là:
operator op(x) đối với hàm thân thiện Biểu thức x op y sẽ đợcchuyển sang sạng: x.operator op(y) đối với hàm thành phần và operator op(x,y) đối với hàm thân thiện
Toán tử tải bội sử dụng với friend:
Để sử dụng hàm toán tử tải bội thân thiện ta chỉ việc khai báo từ khoáfriend ở đầu, sau đó định nghĩa lại toán tử Trong nhiều trờng hợp, kết quảcủa việc sử dụng hàm thành phần giống hệt nh hàm thân thiện Một câu hỏi
đặt ra là tại sao phải phân biệt hai trờng hợp nh thế? Hiển nhiên là vì cónhững tình huống đòi hỏi phải sử dụng hàm thân thiện mà không sử dụnghàm thành phần đợc
Trang 21II.2.2 Chuyển đổi kiểu
Chuyển đổi kiểu là một trong những đặc tính mạnh của C mà cácngôn ngữ khác hầu nh không có đợc Một biểu thức có thể có những hằng,biến ở nhiều kiểu khác nhau và khi thực hiện sẽ áp dụng quy tắc chuyển đổikiểu tự động đợc chơng trình dịch cài đặt sẵn, kiểu dữ liệu ở bên phải phépgán sẽ tự động chuyển đổi sang kiểu ở bên trái Tuy nhiên điều này sẽ khóthực hiện đợc đối với kiểu dữ liệu do ngời sử dụng định nghĩa, bây giờ taxét các phép toán chuyển kiểu trên lớp
Từ kiểu cơ sở sang kiểu lớp Để thực hiện đổi kiểu dữ liệu sang
lớp chúng ta sử dụng toán tử khởi tạo đối tợng
Từ kiểu lớp sang kiểu cơ sở C++ cho phép định nghĩa toán tử quyhồi kiểu tải bội để chuyển dữ liệu kiểu lớp sang dạng kiểu cơ sở.Dạng tổng quát của toán tử quy hồi kiểu tải bội ở dạng hàm:operator double() chuyển lớp vector sang kiểu double Khi đótrong chơng trình chúng ta có thể viết:
double len double(v1); // v1 là đối tợng trong lớp vector hoặc:
Từ một lớp sang một lớp khác: việc chuyển đổi kiểu giữa những
đối tợng ở nhiều lớp khác nhau đợc thực hiện thông qua toán tửkhởi tạo đối tợng hoặc hàm đổi kiểu Hàm đổi kiểu phải là hàmthành phần: operator type_name0 Chuyển đối tợng trong lớp chứa
nó sang kiểu type_name Type_name có thể là kiểu bất kỳ Nếuchuyển kiểu giữa các đối tợng thông qua cấu tử thì thực chất làsao chép dữ liệu giữa các đối tợng
Trang 22II.3 Kế thừa và sự mở rộng các lớp
Khả năng sử dụng lại là đặc tính quan trọng của lập trình hớng đối ợng Việc sử dụng lại những đơn thể chơng trình, những lớp đã đợc pháttriển tốt, đã đợc kiểm nghiệm không những tiếp kiệm đợc tiền của, thờigian mà còn làm tăng thêm những khả năng tơng thích, độ tin cậy của hệthống
t-C++ hỗ trợ rất mạnh cho những khái niệm về sử dụng lại Lớp đợcthiết kế trong C++ luôn luôn có thể đợc sử dụng lại theo nhiều cách khácnhau Khi một lớp đã đợc định nghĩa, đợc kiểm nghiệm thì ngời lập trìnhkhác có thể sử dụng nó trong các mục đích riêng của mình Những lớp này
là lớp cơ sở để tạo ra những lớp mới (lớp dẫn xuất), sử dụng lại những tínhchất trong những lớp đã đợc xác định Cơ chế dẫn xuất ra những lớp mới từnhững lớp trớc gọi là sự kế thừa (hoặc dẫn xuất)
Lớp dẫn xuất có thể kế thừa một số hoặc tất cả những đặc tính củalớp cơ sở, và có thể kế thừa một hay nhiều lớp ở các mức khác nhau C++
cung cấp cho chúng ta 5 loại kế thừa sau:[3]
-};
Trang 23Dấu ':' chỉ ra rằng lớp derrved_class-name đợc dẫn ra từbase_class_name Từ mode là thể khai báo tuỳ chọn, có thể là private hoặc
là public Mặc nhiên là private (không có mode)
Khi lớp dẫn xuất khai báo kế thừa theo kiểu private thì tất cả nhữngthành phần chung public của lớp cơ sở trở thành phần riêng private của lớpdẫn xuất và vì vậy những thành phần public của lớp cơ sở chỉ có thể truynhập đợc thông qua hàm thành phần của lớp kế thừa
Ngợc lại, khi khai báo kế thừa theo kiểu public thì các thành phầnchung của lớp cơ sở cũng trở thành phần chung của lớp dẫn xuất, nên các
đối tợng của lớp dẫn xuất có thể truy nhập đến thành phần public của, lớpcơ sở (hình 3-3)
Trong cả hai trờng hợp, thành phần private của lớp cơ sở hoàn toànkhông đợc kế thừa Vì thế những thành phần private của lớp cơ sở khôngkhi nào trở thành thành phần của lóp dẫn xuất
Dữ liệu và hàmprivate
Dữ liệu và hàmprotected
A
B
Lớp cơ sở
Lớp dẫn xuất
Trang 24*Líp B kÕ thõa kiÓu public tõ líp A:
D÷ liÖu vµ hµm public B
class BVïng private
D÷ liÖu vµ
hµm private B
D÷ liÖu vµ hµm protected A
D÷ liÖu vµ hµm protected B
Vïng private
D÷ liÖu vµ
hµm private B
Trang 25* Lớp B kế thừa kiểu private từ lớp A Lúc đó dữ liệu và hàm của lớp
đều không thực hiện đợc, bởi vì chúng đã trở thành private của lớp B
Hình 3-5 Bổ sung thành phần kế thừa vào vùng private
Chúng ta thấy rằng, những thành phần khai báo ở vùng private củalớp cơ sở không đợc kế thừa Do vậy mà lớp kế thừa của lớp dẫn xuất không
sử dụng đợc những thành phần mà nó kế thừa Chúng ta sẽ thực hiện nh thếnào khi trong lớp dẫn xuất có nhu cầu kế thừa những thành phần dữ liệuprivate của lớp cơ sở Điều này có thể thực hiện đợc bằng cách chuyển dữkiệu thành phần đặc khai báo trong vùng private sang vùng public Nhngkhi đó thì dữ liệu đó lại có thể truy nhập bởi tất cả những thành phần kháctrong chơng trình Điều này phá vỡ nguyên lý che dấu thông tin mà chúng
ta cần thực hiện
Để giải quyết vấn đề trên, C++ đa thêm thể khai báo protected (đợcbảo vệ) cho những thành phần của lớp cơ sở cần đợc kế thừa chỉ trongnhững lớp dẫn xuất trực tiếp Những thành phần đợc khai báo protected cóthể đợc truy nhập bởi những thành phần trong cùng lớp và trong những lớp
Vùng public
Dữ liệu và hàm public B
Vùng private
Dữ liệu và hàm public A
Dữ liệu và hàm private Bclass B
Trang 26dẫn xuất trực tiếp từ lớp cơ sở Nh vậy, để có những thành phần protected tachỉ cần khai báo nh sau:
_ _ _ _ _ };
Mối quan hệ giữa các thành phần của lớp cơ sở và lớp dẫn xuất đợc mô tả trong bảng 3-3
class D1:
class B
Trang 27class X: public D1: public D2
Hình 3-6 Sự tơng ứng trong kế thừa
II.3.2 Kế thừa đa mức
Trong kế thừa đa mức, các lớp đợc tổ chức nh sau:
Lớp dẫn xuất của kế thừa đa mức đợc khai báo nh sau:
class A { .};// lớp cơ sở
class B: public A { .};// B dẫn xuất từ A
class C: public B { }// C dẫn xuất từ B
Quá trình kế thừa có thể đợc mở rộng tuỳ ý, nghĩa các lớp kế thừanhau với số mức tuỳ ý Trong kế thừa đa mức thì nguyên tắc truy nhập củacác lớp dẫn xuất đối với các lớp cơ sở cũng giống nh trong kế thừa đơn và
nó không bị hạn chế bởi các lớp trung gian Có nghĩa là lớp B truy nhập đợc
đến thành phần (dữ liệu và hàm trong vùng protected và public) của lớp A,lớp C truy nhập đợc đến thành phần của lớp B và cũng truy nhập trực tiếp đ-
ợc đến các thành phần của lớp A mà không cần phải thông qua lớp B
II.3.3 Kế thừa phân cấp
Lớp dẫn xuất
Hình 3-7 Kế thừa đa mức
Trang 28Kế thừa là sự phân cấp các lớp, các lớp kế thừa nhau theo một cấutrúc phân cấp đợc gọi là kế thừa phân cấp C++ hỗ trợ cho việc sử dụng cơchế kế thừa để phân cấp các lớp mô tả những cấu trúc đợc thiết kế theo cáchtiếp cận phân cấp Có thể mô tả tổng quá nh sau:
II.3.4 Kế thừa bội
Một lớp có thể kế thừa thuộc tính của nhiều lớp đợc gọi là kế thừabội Kế thừa bội cho phép chúng ta kết hợp đặc trng của một số lớp tạo ralớp mới
Một lớp đợc dẫn xuất từ nhiều lớp cơ sở đợc khai báo nh sau:
class B: mode A1, mode A2, , mode An
A31A22
A21A11
Hình 3-8 Kế thừa phân cấp
Trang 29Kế thừa kép là sự kết hợp của kế thừa đa thức và kế thừa bội Nghĩa
là một lớp dẫn xuất có thể kế thừa nhiều lớp cơ sở và ở nhiều mức khácnhau
II.3.6 Các lớp cơ sở ảo
Trong thức tế đôi khi chúng ta gặp tình huống đòi hỏi phải sử dụngkết hợp cả ba loại kế thừa: kế thừa bội, đa mức và phân cấp gọi là kế thừalai ghép
Ví dụ:
Lớp kế thừa trực tiếp hai lớp con CHA và Mẹ Ngoài ra nó còn kếthừa từ ông bà theo hai đờng khác nhau Nó kế thừa trực tiếp, một số đặctính của ông bà (theo đờng - - - ) và gán tiếp qua cha, mẹ ( hai lớp cơ
sở trung gian) Nh vậy những thành phần public và protected của ông bà
sẽ đợc kế thừa đúp ở lớp con, lần thứ nhất là kế thừa từ cha, lần thứ hai
kế thừa từ mẹ Nghĩa là lớp con sẽ có hai tập các thành phần kế thừagiống nhau Do vậy chúng ta phải loại bỏ d thừa Trong C++ cho phép loại
ông_bà
mẹcha
Trang 30bỏ những thành phần d thừa này bằng cách khai báo lớp cơ sở ảo (virtualbase class) Lúc đó chúng ta khai báo nh sau:
II.3.7 Cấu tử trong các lớp dẫn xuất
Cấu tử đợc sử dụng để tạo lập các đối tợng Nhng việc tạo lập các đốitợng trong những lớp kế thừa đợc thực hiện nh thế nào? Chúng ta thấy cónhững điểm khác biệt nh sau: nếu trong lớp cơ sở không có một cấu tử nào
có tham biến thì trong lớp dẫn xuất không phải có hàm cấu tử Song nếumột lớp cơ sở nào đó có chứa cấu tử có tham biến thì lớp dẫn xuất cũngphải có cấu tử và các tham số thực sự sẽ đợc truyền tơng ứng cho các cấu tử
có tham biến trong các lớp cơ sở Cả hai lớp cơ sở và dẫn xuất đều có cấu tửthì cấu tử của lớp cơ sở thực hiện trớc rồi sau đó đến lớp cấu tử của lớp dẫnxuất Trong trờng hợp kế thừa bội thì các cấu tử của lớp đợc thực hiện lần l-
ợt theo thứ tự mà chúng đợc khai báo trong lớp dẫn xuất
Trong trờng hợp kế thừa đa mức thì các cấu tử đợc thực hiện theo thứ
tự kế thừa theo đa mức
Cấu tử của lớp dẫn xuất đợc định nghĩa nh sau:
Trang 31Trong đó phần đầu của phơng_thức_thiết_lập_tử_dẫn_xuất bao gồmhai thành phần cách nhau bằng hai dấu chấm ‘:’.Đầu tiên là khai báo danhsách những tham biến sẽ đợc truyền cho các cấu tử ở lớp dẫn xuất là ph-
ơng_thức_thiết_lập_dẫn_xuất (DS1, DS2, ,DSn, DSDX), sau đó là các lờigọi tới các hàm cấu tử đã đợc định nghĩa ở những lớp cơ sở làCơ_sở_1(DS1), , Cơ_sở_n(DSn) Trong đó DS1, DS2, , DSn là nhữngdanh sách tham biến đợc sử dụng để tạo lập các đối tợng Ví dụ:
D (int a1, a2, float b1, float b2, int d1):
A(a1, a2), // gọi cấu tử A trong lớp A B(b1, b2), // gọi cấu tử B trong lớp B {
với tơng ứng bội ta có thể sử dụng hàm ảo (virtual function).
Trang 32 Hoặc thêm từ khoá virtual vào dòng tiêu đề của phơng thức bêntrong định nghĩa của lớp cơ sở.
Hoặc thêm từ khoá virtual vào dòng tiêu đề bên trong định nghĩacủa tất cả các lớp A, B, C, D
Quy tắc gọi phơng thức ảo
Phơng thức ảo đợc gọi thông qua một con trỏ của lớp cơ sở, lúc đóphơng thức của lớp nào đợc gọi phụ thuộc vào đối tợng mà con trỏ đang trỏtới
Với các lớp A, B, C, D đã đợc định nghĩa, để truy nhập đến hàmhiển_thị() của các lớp ta khai báo nh sau:
A*p; // p là con trỏ kiểu A
A a; B b; Cc; Dd; //khai báo các đối tợng
p=&a;// p trỏ tới đối tợng a của lớp A
p->hiển_thị(); // gọi tới A:: hiển_thị()
p=&b; // p trỏ tới đối tợng b của lớp B
p->hiển_thị(); // gọi tới B::hiển_thị()
p=&c;// p trỏ tới đối tợng c của lớp C
p->hiển_thị(); // gọi tới C::hiển_thị()
Hàm ảo phải tuân theo những quy tắc sau:
1 Hàm ảo phải là hàm thành phần của lớp
2 Những thành phần tĩnh không thể khai báo ảo đợc
3 Sử dụng con trỏ để truy nhập đến các hàm ảo
4 Hàm ảo có thể là hàm thân thiện (friend) của lớp khác
5 Hàm ảo phải đợc định nghĩa trong lớp cơ sở hoặc cả trong lớp cơ
sở và lớp dẫn xuất, ngay cả khi không sử dụng nó
Trang 336 Mẫu của tất cả các phiên bản (lớp cơ sở và lớp dẫn xuất) phảigiống nhau Nếu hai hàm cùng tên nhng giống nhau thì C++ xem làtoán tử tải bội.
7 Không đợc tạo ra toán tử ảo, nhng có thể tạo ra đợc phơng thứchuỷ bỏ ảo
8 Con trỏ kiểu lớp cơ sở có thể dùng để xác định đối tợng lớp dẫnxuất, nhng ngợc lại thì không
9 Không dùng đợc phép tăng giảm giá trị con trỏ đối với lớp dẫnxuất, mà chỉ có tác dụng với lớp cơ sở
Chơng III Hàm và lớp mẫu
III.1 Hàm mẫu
III.1.1 Định nghĩa
Khi chúng ta muốn tạo ra một chơng trình C++ thực hiện các côngviệc nào đó cho tất cả các kiểu dữ liệu tất nhiên ta sẽ sử dụng hàm nạpchồng (function overloading) Chẳng hạn ta muốn tạo các hàm tính bình ph-
ơng số int và float, ta sẽ phải tạo hai hàm:
int Square(int x){
Trang 34đặt hàm tổng quát về dữ liệu, khi sử dụng sẽ chỉ định cụ thể để trình biêndịch hiểu đợc Hàm nh vậy đợc gọi là hàm mẫu (template) nh ví dụ trên ta
có thể viết lại nh sau:
cout << “Square(2)=”<<Square(2)<< endl;
cout << “Square(7.1)=”<<Square(7.1)<< endl;
}
Trong lần gọi thứ nhất, hàm Square có tham số là int nên trình biêndịch sẽ tạo ra hàm int Square (int), lần hai tạo ra hàm có dạng float Square(float)
III.1.2 Hàm mẫu có nhiều tham số hình thức
Trang 35Trờng hợp hàm mẫu có nhiều tham số cùng kiểu, khi trình biên dịchbiết đợc kiểu thứ nhất thì các tham số còn lại mang cùng kiểu mẫu sẽ nhậnkiểu của tham số thứ nhất.
III.1.3 Hàm mẫu có nhiều tham số khác nhau
Hàm template có nhiều tham số với kiểu khác nhau Tuy nhiên nóvẫn mang đầy đủ tính chất của hàm mẫu đơn giản
Trang 36float abs(float a){
for (int i=0,float s=0;i<5;i++)
Trang 37Đầu tiên chơng trình sẽ tìm hàm có tham số phù hợp nếukhông tìm thấy nó sẽ gọi hàm mẫu Trong chơng trình có hai hàmabs nhng do cách truyền tham số thực và sự hiện diện của hàm floatabs(float) Chơng trình dịch sẽ lựa chọn đúng để thực hiện và biêndịch.
Một hàm mẫu ra lệnh cho chơng trình dịch cách tạo ra một tậpcác hàm nạp chồng Chơng trình dịch chỉ sinh ra mã cho các kiểudữ liệu khi nó gọi hàm mẫu
III.2 Lớp mẫu
III.2.1 Định nghĩa
Cũng giống nh hàm mẫu, lớp mẫu cũng mang đầy đủ tính chất, t tởngcủa hàm mẫu bằng cách cài đặt một lớp chung tổng quát nào đó Khi sửdụng cho từng trờng hợp cụ thể lớp sẽ mang kiểu dữ liệu xác định Đây làcông cụ mạnh để xây dựng các lớp chứa
Trang 38 Lớp mẫu có thể là tham số cho một lớp mẫu khác:
Record <int, Object<string>> rec;
III.2.2 Lớp mẫu có tham số
Ngôn ngữ lập trình hớng đối tợng C++ cho phép tạo ra các lớp mẫulinh động bằng cách cho phép thay đổi giá trị của các thành phần bên tronglớp Khi đó lớp có dạng của một hàm với tham số hình thức
template <class T, size_t MAX>
class Stack{ }
Chú ý:
Khi định nghĩa một lớp mẫu, mỗi lớp mẫu có phơng thức và dữ liệuriêng của nó Cho nên càng nhiều lớp mẫu thì chơng trình càng cần nhiều
Trang 39bộ nhớ Phần lớn các mẫu sẽ đợc định nghĩa trong các tệp chứa khai báo và
sẽ đợc dịch gộp (include) khi sử dụng lớp đó
III.3 Kết luận
Các hàm và lớp mẫu cho phép tạo ra một họ các hàm và các lớp đểtác động đến các kiểu dữ liệu khác nhau Với những đặc điểm nổi bật này,chơng trình hớng đối tợng hoàn toàn linh động và mang tính kế thừa cao
Đồng thời nó giúp cho ngời lập trình không phải viết lại những đoạn mãgiống nhau, cũng nh làm thiểu mã nguồn một cách đáng kể
Chơng IV Cấu trúc dữ liệu & Các lớp mẫu
IV Cấu trúc dữ liệu
Các chơng trình thờng chứa hai phần: giải thuật và cấu trúc dữ liệu.Một chơng trình tốt là chơng trình hoà hợp đợc cả hai vấn đề này Sự chọnlựa và thi hành của một cấu trúc dữ liệu đợc xem là quan trọng ngang vớicác trình vận dụng nó Do đó, việc có phơng pháp đúng lu và truy xuất dữliệu trong một số trờng hợp là rất quan trọng
Cấu trúc dữ liệu đợc xem nh một tập các dịch vụ cung cấp cho thếgiới bên ngoài, Ngời sử dụng không quan tâm đến việc lu trữ cụ thể trên cácthiết bị vật lý nh thế nào,mà chỉ quan tâm đến việc truy cập – tức là lu vào
và phục hồi nh thế nào
Các kiểu cấu trúc dữ liệu cơ bản sau mà tôi đề cập trong cuốn tiểuluận này:
Hàng đợi (Queue)
Hàng quay tròn (Circle)
Ngăn xếp (Stack)
Trang 40 Danh sách liên kết đơn (Simple List).
Danh sách liên kết đôi (double List)
Cây nhị phân (Binary Tree)
IV.1.1 Lớp chứa
Do các tính chất chung cơ bản của các biểu cấu trúc dữ liệu tuyếntính ngăn xếp hàng và hàng xoay nên tôi đã xây dựng lớp chứa thuần ảoSequence vì các lý do sau:
Sử dụng đợc sự thừa kế, tránh phải viết lại các phơng thức dữ liệu