Xem mẫu

  1. LËp tr×nh h-íng ®èi t-îng MỤC LỤC Mục lục ..................................................................................................................... 1 Chương 1: Lập trình hướng đối tượng và C++ ....................................................... 5 1.1. Lập trình hướng đối tượng là gì....................................................................... 5 1.2. Các ngôn ngữ và một vài ứng dụng hướng đối tượng ..................................... 5 1.3. Một số khái niệm trong lập trình hướng đối tượng ......................................... 6 1.3.1. Sự đóng gói ............................................................................................... 6 1.3.2. Lớp và thực thể ......................................................................................... 7 1.3.3. Tính thừa kế .............................................................................................. 7 1.3.4. Tính đa hình .............................................................................................. 7 1.3.5. Phương thức ảo ......................................................................................... 8 1.4. Một số mở rộng đơn giản trong C++ so với C ............................................... 8 1.4.1. Môi trường C++........................................................................................ 8 1.4.2. Lập trình cấu trúc và lập trình hướng đối tượng ...................................... 9 1.4.3. Cách viết dòng ghi chú ........................................................................... 11 1.4.4. Khai báo linh hoạt và hằng có kiểu ........................................................ 12 1.4.5. Các kiểu char và int ................................................................................ 13 1.4.6. Lấy địa chỉ các phần tử mảng thực hai chiều ......................................... 13 1.4.7.Vào ra trong C++ ..................................................................................... 14 1.4.8. Cấu trúc trong C++ ................................................................................. 15 1.4.9. Cấp phát bộ nhớ trong C++ .................................................................... 15 1.5. Hàm trong C++ .............................................................................................. 19 1.5.1. Biến tham chiếu ...................................................................................... 19 1.5.2. Truyền giá trị cho hàm theo biến tham chiếu ......................................... 20 1.5.3. Hàm trả về các tham chiếu ..................................................................... 20 1.5.4. Đối có giá trị mặc định ........................................................................... 21 1.5.5. Các hàm trực tuyến (inline) .................................................................... 21 1.5.6. Định nghĩa chồng các hàm ..................................................................... 22 1.5.7. Định nghĩa chồng các toán tử ................................................................. 22 Câu hỏi và Bài tập .................................................................................................. 31 Chương 2: Lớp và đối tượng ................................................................................ 39 2.1. Định nghĩa lớp ............................................................................................... 39 2.2. Phạm vi truy xuất ........................................................................................... 40 2.3. Đối tượng ....................................................................................................... 41 2.3.1. Biến, mảng đối tượng ............................................................................. 41 2.3.2. Con trỏ đối tượng ................................................................................... 42 Trang - 1 -
  2. LËp tr×nh h-íng ®èi t-îng 2.3.3. Đối của phương thức, con trỏ this .......................................................... 42 2.4. Hàm và các phương thức của lớp .................................................................. 43 2.4.1. Hàm và hàm bạn ..................................................................................... 43 2.4.2. Phương thức toán tử ............................................................................... 49 2.4.3. Hàm tạo .................................................................................................. 54 2.4.4. Lớp không có hàm tạo và hàm tạo mặc định ......................................... 55 2.4.5. Hàm tạo sao chép ................................................................................... 58 2.4.6. Hàm huỷ ................................................................................................. 61 2.4.7. Toán tử gán ............................................................................................. 63 2.4.8. Phân loại các phương thức ..................................................................... 64 2.4.9. Hàm tạo và đối tượng thành phần .......................................................... 65 2.5. Các thành phần tĩnh ....................................................................................... 70 2.5.1. Thành phần dữ liệu tĩnh ......................................................................... 70 2.5.2. Phương thức tĩnh .................................................................................... 73 2.6. Khởi gán mảng đối tượng .............................................................................. 75 2.7. Cấp phát bộ nhớ cho đối tượng ..................................................................... 76 2.8. Đối tượng hằng, phương thức hằng............................................................... 76 2.9. Hàm bạn, lớp bạn .......................................................................................... 81 Câu hỏi và bài tập................................................................................................... 82 Chương 3: Dẫn xuất và thừa kế ............................................................................ 88 3.1. Sự dẫn xuất và tính thừa kế ........................................................................... 88 3.1.1. Lớp cơ sở và lớp dẫn xuất ...................................................................... 88 3.1.2. Cách xây dựng lớp dẫn xuất ................................................................... 88 3.1.3. Các kiểu thừa kế ..................................................................................... 89 3.1.4. Thừa kế các thành phần dữ liệu.............................................................. 90 3.1.5. Thừa kế phương thức ............................................................................. 91 3.2. Hàm tạo và hàm huỷ đối với tính thừa kế ..................................................... 95 3.2.1. Xây dựng hàm tạo của lớp dẫn xuất ....................................................... 95 3.2.2. Hàm huỷ của lớp dẫn xuất ...................................................................... 98 3.3. Phạm vi truy xuất đến các thành phần của lớp cơ sở .................................. 100 3.4. Thừa kế nhiều mức và sự trùng tên ............................................................. 104 3.4.1. Sơ đồ xây dựng các lớp dẫn xuất theo nhiều mức ............................... 104 3.4.2. Sự thừa kế nhiều mức ........................................................................... 105 3.4.3. Sự trùng tên .......................................................................................... 105 3.4.4. Sử dụng các thành phần trong lớp dẫn xuất ......................................... 106 3.5. Lớp cơ sở ảo ................................................................................................ 107 3.5.1. Một số lớp cơ sở xuất hiện nhiều lần trong lớp dẫn xuất ..................... 107 Trang - 2 -
  3. LËp tr×nh h-íng ®èi t-îng 3.5.2. Các lớp cơ sở ảo ................................................................................... 107 3.6. Toán tử gán của lớp dẫn xuất ...................................................................... 108 3.6.1. Khi nào cần xây dựng toán tử gán ........................................................ 108 3.6.2. Cách xây dựng toán tử gán cho lớp dẫn xuất ....................................... 108 3.7. Hàm tạo sao chép của lớp dẫn xuất ............................................................. 108 3.7.1. Khi nào cần xây dựng hàm tạo sao chép .............................................. 108 3.7.2. Cách xây dựng hàm tạo sao chép cho lớp dẫn xuất ............................. 109 3.8. Phương thức tĩnh ......................................................................................... 110 3.9. Sự hạn chế của phương thức tĩnh ................................................................ 112 3.10. Phương thức ảo và tương ứng bội ............................................................. 112 3.10.1. Cách định nghĩa phương thức ảo ........................................................ 112 3.10.2. Quy tắc gọi phương thức ảo ............................................................... 113 3.10.3. Tương ứng bội .................................................................................... 116 3.10.4. Liên kết động ...................................................................................... 119 3.10.5. Quy tắc gán địa chỉ đối tượng cho con trỏ lớp cơ sở.......................... 130 3.11. Lớp cơ sở trừu tượng ................................................................................. 130 Câu hỏi và bài tập ................................................................................................. 135 Chương 4: Khuôn hình ........................................................................................ 141 4.1. Khuôn hình hàm .......................................................................................... 141 4.1.1. Khái niệm khuôn hình hàm .................................................................. 141 4.1.2. Tạo một khuôn hình hàm ...................................................................... 141 4.1.3. Sử dụng khuôn hình hàm ...................................................................... 142 4.1.4. Các tham số kiểu của khuôn hình hàm ................................................. 145 4.1.5. Giải thuật sản sinh một hàm thể hiện ................................................... 146 4.1.6. Khởi tạo các biến có kiểu dữ liệu chuẩn .............................................. 147 4.1.7. Các hạn chế của khuôn hình hàm ......................................................... 148 4.1.8. Các tham số biểu thức của một khuôn hình hàm ................................. 149 4.1.9. Định nghĩa chồng các khuôn hình hàm ................................................ 150 4.2. Khuôn hình lớp ............................................................................................ 152 4.2.1. Khái niệm khuôn hình lớp .................................................................... 152 4.2.2. Tạo một khuôn hình lớp ....................................................................... 153 4.2.3. Sử dụng khuôn hình lớp ....................................................................... 158 4.2.4. Các tham số trong khuôn hình lớp ....................................................... 158 4.2.5. Các tham số biểu thức trong khuôn hình lớp ....................................... 160 4.2.6. Tổng quát về khuôn hình lớp ................................................................ 162 4.2.7. Cụ thể hoá khuôn hình lớp ................................................................... 162 4.2.8. Sự giống nhau của các lớp thể hiện ...................................................... 165 Trang - 3 -
  4. LËp tr×nh h-íng ®èi t-îng 4.2.9. Các lớp thể hiện và các lớp bạn bè ....................................................... 166 Câu hỏi và bài tập................................................................................................. 173 Chương 5: Các dòng xuất nhập .......................................................................... 174 5.1. Các lớp stream ............................................................................................. 174 5.2. Dòng cin và toán tử nhập ............................................................................ 175 5.3. Dòng cout và toán tử xuất ........................................................................... 176 5.4. Các phương thức định dạng ........................................................................ 178 5.4.1. Nội dung định dạng giá trị xuất ............................................................ 178 5.4.2. Các phương thức định dạng ................................................................. 180 5.5. Cờ định dạng ............................................................................................... 182 5.5.1. Khái niệm chung về cờ ......................................................................... 182 5.5.2. Công dụng của các cờ .......................................................................... 182 5.5.3. Các phương thức bật tắt cờ................................................................... 186 5.6. Các dòng tin chuẩn ...................................................................................... 187 5.7. Ghi dữ liệu lên tệp ....................................................................................... 187 5.8. Đọc dữ liệu từ tệp ........................................................................................ 193 5.9. Đọc ghi dữ liệu đồng thời trên tệp .............................................................. 197 Câu hỏi và bài tập................................................................................................. 244 Một số thông báo lỗi thường gặp ........................................................................ 248 Tài liệu tham khảo ................................................................................................ 253 Trang - 4 -
  5. LËp tr×nh h-íng ®èi t-îng Chương 1: Lập trình hướng đối tượng và C++ Nội dung của chương tập trung trình bày các vấn đề sau:  Lập trình hướng đối tượng là gì?  Một số khái niệm trong lập trình hướng đối tượng.  Giới thiệu về C++ và một số mở rộng của C++ so với C.  Hàm trong C++. 1.1. Lập trình hướng đối tượng là gì Vào những ngày đầu phát triển của máy tính, khi các phần mềm còn rất đơn giản chỉ cỡ vài chục dòng lệnh, chương trình được viết tuần tự với các câu lệnh được thực hiện từ đầu đến cuối. Cách lập trình như vậy được gọi là phương pháp lập trình tuyến tính. Khoa học máy tính ngày càng phát triển, các phần mềm đòi hỏi ngày một phức tạp và lớn hơn rất nhiều. Vì vậy, xuất hiện một phương pháp lập trình mới gọi là lập trình cấu trúc. Theo phương pháp này, chương trình được tổ chức thành các chương trình con. Mỗi chương trình con đảm nhận xử lý một công việc nhỏ trong toàn bộ hệ thống. Mỗi chương trình con này lại có thể chia nhỏ thành các chương trình con nhỏ hơn. Quá trình phân chia như vậy cứ tiếp diễn cho tới khi các chương trình con nhận được là đủ đơn giản để giải quyết. Người ta gọi quá trình đó là “làm mịn dần”. Theo quan điểm của phương pháp này: Chương trình = Cấu trúc dữ liệu + Giải thuật. Vì vậy, để lập được một chương trình đòi hỏi người lập trình phải có kiến thức vững vàng về Cấu trúc dữ liệu. Một khó khăn nữa gặp phải là chương trình phụ thuộc chặt chẽ vào cấu trúc dữ liệu. Do vậy, chỉ cần một thay đổi nhỏ ở cấu trúc dữ liệu có thể phải viết lại cả chương trình, điều này không thích hợp khi xây dựng một dự án phần mềm lớn. Một phương pháp lập trình đang được sử dụng phổ biến hiện nay đã khắc phục được nhược điểm này của phương pháp lập trình cấu trúc đó chính là lập trình hướng đối tượng. Lập trình hướng đối tượng đặt trọng tâm vào các đối tượng (dữ liệu của hệ thống), không cho phép dữ liệu biến động tự do trong hệ thống. Lập trình hướng đối tượng có những đặc điểm 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 các đối tượng - Cấu trúc dữ liệu được thiết kế sao cho đặc tả được đối tượng - Các hàm thao tác trên các vùng dữ liệu của đối tượng được gắn với cấu trúc dữ liệu đó Trang - 5 -
  6. LËp tr×nh h-íng ®èi t-îng - Dữ liệu được đóng gói lại, được che dấu và không cho phép các hàm ngoại lai truy nhập tự do - Các đối tượng tác động và trao đổi thông tin với nhau qua các hàm - Có thể dễ dàng bổ sung dữ liệu và các hàm mới vào đối tượng nào đó khi cần thiết. 1.2. Các ngôn ngữ và một vài ứng dụng hướng đối tượng Lập trình hướng đối tượng không phải là đặc quyền của một ngôn ngữ lập trình đặc biệt nào. Cũng giống như kỹ thuật lập trình có cấu trúc, các khái niệm trong lập trình hướng đối tượng được thể hiện trong nhiều ngôn ngữ lập trình khác nhau. Những ngôn ngữ cung cấp được những khả năng lập trình hướng đối tượng (tạo lớp, đối tượng, thừa kế,…) được gọi là ngôn ngữ lập trình hướng đối tượng. Một số ngôn ngữ lập trình hướng đối tượng đang dùng phổ biến hiện nay như: C++, Java, C#, Visual Basic.Net,.. Lập trình là một trong những thuật ngữ được nhắc đến nhiều nhất hiện nay trong công nghệ phần mềm và nó được ứng dụng để phát triển phần mềm trong nhiều lĩnh vực khác nhau. Trong số đó, ứng dụng quan trọng và nổi tiếng nhất hiện nay là thiết kế giao diện với người sử dụng, kiểu như Windows. Các lĩnh vực ứng dụng phù hợp với kỹ thuật lập trình hướng đối tượng có thể liệt kê như dưới đây:  Các hệ thống làm việc theo thời gian thực;  Các hệ mô hình hoá hoặc mô phỏng các quá trình;  Các hệ cơ sở dữ liệu hướng đối tượng;  Các hệ siêu văn bản (hypertext), đa phương tiện (multimedia);  Các hệ thống trí tuệ nhân tạo và các hệ chuyên gia;  Các hệ thống song song và mạng nơ-ron;  Các hệ tự động hoá văn phòng hoặc trợ giúp quyết định;  Các hệ CAD/CAM.  … 1.3. Một số khái niệm trong lập trình hướng đối tượng 1.3.1. Sự đóng gói Trong phương pháp lập trình cấu trúc các hàm hay thủ tục có phạm vi hoạt động trong toàn bộ chương trình, nó được sử dụng thông qua các lời gọi mà không cần Trang - 6 -
  7. LËp tr×nh h-íng ®èi t-îng biết đến nội dung cụ thể của nó. Người sử dụng chỉ cần biết chức năng của hàm cũng như các tham số cần truyền vào để gọi hàm chạy mà không cần quan tâm đến những lệnh cụ thể bên trong nó. Người ta gọi đó là sự đóng gói về chức năng. Trong phương pháp lập trình hướng đối tượng, không những các chức năng được đóng gói mà cả dữ liệu cũng như vậy. Với mỗi đối tượng người ta không thể truy nhập trực tiếp vào các thành phần dữ liệu của nó mà phải thông qua các thành phần chức năng (các phương thức) để làm việc đó. 1.3.2. Lớp và thực thể Đối tượng (hay thực thể) là sự kết hợp giữa dữ liệu và thủ tục (hay còn gọi là phương thức - method) thao tác trên dữ liệu đó. Có thể đưa ra công thức phản ánh bản chất kỹ thuật của lập trình hướng đối tượng như sau: Đối tượng = Dữ liệu + Phương thức Lớp là một tập các đối tượng có cấu trúc dữ liệu và các phương thức giống nhau (hay nói cách khác là một tập các đối tượng cùng loại). Như vậy, khi có một lớp thì sẽ biết được một mô tả cấu trúc dữ liệu và phương thức của các đối tượng thuộc lớp đó. Mỗi đối tượng sẽ là một thể hiện cụ thể (instance) của lớp đó. Trong lập trình, có thể coi một lớp như là một kiểu dữ liệu, còn các đối tượng sẽ là các biến có kiểu của lớp. 1.3.3. Tính thừa kế Tính thừa kế là khả năng cho phép định nghĩa một lớp mới trên cơ sở các lớp đã tồn tại, tất nhiên có bổ sung những phương thức hay các thành phần dữ liệu mới. Khả năng thừa kế cho phép dễ dàng chỉnh sửa và phát triển chương trình. Rõ ràng đây là một điểm mạnh của lập trình hướng đối tượng so với lập trình cấu trúc. 1.3.4. Tính đa hình Đó là khả năng cho phép một thông điệp (lời gọi phương thức) có thể thay đổi cách thực hiện của nó theo lớp cụ thể của đối tượng nhận lời gọi phương thức. Khi một lớp dẫn xuất được tạo ra, nó có thể thay đổi cách thực hiện các phương thức nào đó mà nó thừa hưởng từ lớp cơ sở của nó. Một lời gọi phương thức từ đối tượng của lớp cơ sở, sẽ thực hiện phương thức đó trong lớp cơ sở. Nếu một lớp dẫn xuất định nghĩa lại một phương thức thừa hưởng từ lớp cơ sở của nó thì một lời gọi phương thức cùng tên với phương thức này, khi được gửi tới một đối tượng của lớp dẫn xuất sẽ gọi phương thức đã định nghĩa cho lớp dẫn xuất. Trang - 7 -
  8. LËp tr×nh h-íng ®èi t-îng 1.3.5. Phương thức ảo C++ cũng cho phép cơ chế tương ứng bội bằng cách định nghĩa một phương thức là phương thức ảo trong sơ đồ thừa kế. Khi đó, một con trỏ lớp cơ sở có thể trỏ đến địa chỉ của một đối tượng lớp dẫn xuất, và phương thức được thực hiện là tuỳ thuộc vào kiểu của đối tượng mà con trỏ đang trỏ tới. 1.4. Một số mở rộng đơn giản trong C++ so với C 1.4.1. Môi trường C++ C là một ngôn ngữ lập trình mạnh và linh hoạt được sử dụng rộng rãi để giải các bài toán khoa học kỹ thuật, ghép nối máy tính, đồ hoạ,... Để thừa kế những điểm mạnh vốn có của C vào năm 1983, giáo sư Bjarne Stroustrap bắt đầu nghiên cứu và phát triển việc cài đặt khả năng lập trình hướng đối tượng vào ngôn ngữ C tạo ra một ngôn ngữ mới gọi là C++. Hai dấu + trong tên gọi C++ thể hiện hai đặc điểm mới của C++ so với C. Đặc điểm thứ nhất là một số khả năng mở rộng so với C như tham chiếu, chồng hàm, tham số mặc định... Đặc điểm thứ hai chính là khả năng lập trình hướng đối tượng. Hiện nay C++ chưa phải là một ngôn ngữ hoàn toàn ổn định. Kể từ khi phiên bản đầu tiên ra đời vào năm 1986 đã có rất nhiều thay đổi trong các phiên bản C++ khác nhau: bản 1.1 ra đời vào năm 1986, 2.0 vào năm 1989 và 3.0 vào năm 1991. Phiên bản 3.0 này được sử dụng để làm cơ sở cho việc định nghĩa một ngôn ngữ C++ chuẩn (kiểu như ANSI C). Trên thực tế hiện nay tất cả các chương trình dịch C++ đều tương thích với phiên bản 3.0. Vì vậy C++ hầu như không gây bất kỳ một khó khăn nào khi chuyển đổi từ một môi trường này sang môi trường khác. C++ chứa đựng khái niệm lớp. Một lớp bao gồm các thành phần dữ liệu bao gồm các thuộc tính và các phương thức( hay là hàm thành phần). Từ một lớp có thể tạo ra các đối tượng hoặc bằng cách khai báo thông thường một biến có kiểu là lớp đó hoặc bằng cách cấp phát bộ nhớ động nhờ sử dụng toán tử new. C++ cho phép đóng gói dữ liệu nhưng nó không bắt buộc chúng ta thực hiện điều đó. Đây là một nhược điểm của C++. Tuy nhiên cũng cần thấy rằng bản thân C++ chỉ là sự mở rộng của C nên nó không thể là một ngôn ngữ lập trình hướng đối tượng thuần khiết được. C++ cho phép định nghĩa các hàm tạo (constructor) cho một lớp. Hàm tạo là một phương thức đặc biệt được gọi đến tại thời điểm một đối tượng của lớp được tạo ra. Trang - 8 -
  9. LËp tr×nh h-íng ®èi t-îng Hàm tạo có nhiệm vụ khởi tạo một đối tượng: cấp phát bộ nhớ, gán các giá trị cho các thành phần dữ liệu cũng như việc chuẩn bị chỗ cho các đối tượng mới. Một lớp có thể có một hay nhiều hàm tạo. Để xác định hàm tạo nào cần gọi đến, chương trình biên dịch sẽ so sánh các đối số với các tham số truyền vào. Tương tự như hàm tạo, một lớp có thể có một hàm huỷ (destructor), một phương thức đặc biệt được gọi đến khi đối tượng được giải phóng khỏi bộ nhớ. Lớp trong C++ thực chất là một kiểu dữ liệu do người sử dụng định nghĩa. Khái niệm định nghĩa chồng toán tử cho phép định nghĩa các phép toán trên một lớp giống như các kiểu dữ liệu chuẩn của C. Ví dụ chúng ta có thể định nghĩa một lớp số phức với các phép toán cộng, trừ, nhân, chia. Cũng giống như C, C++ có khả năng chuyển đổi kiểu. Không những thế, C++ còn cho phép mở rộng sự chuyển đổi này sang các kiểu do người sử dụng tự định nghĩa (các lớp). Ví dụ, chúng ta có thể chuyển đổi từ kiểu chuẩn int của C sang kiểu số phức mà ta định nghĩa chẳng hạn. C++ cho phép thực hiện thừa kế các lớp đã xây dựng. Từ phiên bản 2.0 trở đi, C++ còn cho phép một lớp thừa kế cùng một lúc từ nhiều lớp khác nhau (gọi là sự đa thừa kế). Cuối cùng C++ cung cấp những thao tác vào ra mới dựa trên cơ sở khái niệm luồng dữ liệu (flow). Sự ưu việt của các thao tác này ở chỗ: * Sử dụng đơn giản. * Kích thước bộ nhớ được rút gọn. * Khả năng áp dụng trên các kiểu do người sử dụng định nghĩa bằng cách sử dụng cơ chế định nghĩa chồng toán tử. 1.4.2. Lập trình cấu trúc và lập trình hướng đối tượng Đặc trưng của lập trình hướng cấu trúc Trong lập trình hướng cấu trúc, chương trình chính được chia nhỏ thành các chương trình con và mỗi chương trình con thực hiện một công việc xác định. Chương trình chính sẽ gọi đến chương trình con theo một giải thuật, hoặc một cấu trúc được xác định trong chương trình chính. Các ngôn ngữ lập trình cấu trúc phổ biến là Pascal, C và C++. Riêng C++ ngoài việc có đặc trưng của lập trình cấu trúc Trang - 9 -
  10. LËp tr×nh h-íng ®èi t-îng do thừa kế từ C, còn có đặc trưng của lập trình hướng đối tượng. Cho nên C++ còn được gọi là ngôn ngữ lập trình nửa cấu trúc, nửa hướng đối tượng. Đặc trưng cơ bản nhất của lập trình cấu trúc thể hiện ở mối quan hệ: Chương trình = Cấu trúc dữ liệu + Giải thuật Cấu trúc dữ liệu là cách tổ chức dữ liệu cho việc xử lý bởi một hay nhiều chương trình nào đó. Giải thuật là một quy trình để thực hiện một công việc xác định. Trong chương trình, giải thuật có quan hệ phụ thuộc vào cấu trúc dữ liệu: Một cấu trúc dữ liệu chỉ phù hợp với một số hạn chế các giải thuật. Nếu thay đổi cấu trúc dữ liệu thì phải thay đổi giải thuật cho phù hợp. Một giải thuật thường phải đi kèm với một cấu trúc dữ liệu nhất định. Tính chất Mỗi chương trình con có thể được gọi thực hiện nhiều lần trong một chương trình chính. Các chương trình con có thể được gọi đến để thực hiện theo một thứ tự bất kì, tuỳ thuộc vào giải thuật trong chương trình chính mà không phụ thuộc vào thứ tự khai báo của các chương trình con. Các ngôn ngữ lập trình cấu trúc cung cấp một số cấu trúc lệnh điều khiển chương trình. Ưu điểm  Chương trình sáng sủa, dễ hiểu, dễ theo dõi.  Tư duy giải thuật rõ ràng. Nhược điểm  Lập trình cấu trúc không hỗ trợ mạnh việc sử dụng lại mã nguồn: Giải thuật luôn phụ thuộc chặt chẽ vào cấu trúc dữ liệu. Do đó, khi thay đổi cấu trúc dữ liệu, phải thay đổi giải thuật, nghĩa là phải viết lại chương trình.  Không phù hợp với các phần mềm lớn: tư duy cấu trúc với các giải thuật chỉ phù hợp với các bài toán nhỏ, nằm trong phạm vi một module của chương trình. Với dự án phần mềm lớn, lập trình cấu trúc tỏ ra không hiệu quả trong việc giải quyết mối quan hệ vĩ mô giữa các module của phần mềm. Đặc trưng của lập trình hướng đối tượng Trong lập trình hướng đối tượng: Ta coi các thực thể trong chương trình là các đối tượng và sau đó trừu tượng hoá đối tượng thành lớp đối tượng. Trang - 10 -
  11. LËp tr×nh h-íng ®èi t-îng Dữ liệu được tổ chức thành các thuộc tính của lớp. Nguời ta ngăn chặn việc thay đổi tuỳ tiện dữ liệu trong chương trình bằng các cách giới hạn truy nhập như chỉ cho phép truy nhập dữ liệu thông qua đối tượng, thông qua các phương thức mà đối tượng được cung cấp… Quan hệ giữa các đối tượng là quan hệ ngang hàng hoặc quan hệ thừa kế: Nếu lớp B thừa kế từ lớp A thì A được gọi là lớp cơ sở và B được gọi là lớp dẫn xuất. Lập trình hướng đối tượng có hai đặc trưng cơ bản:  Đóng gói dữ liệu: dữ liệu luôn được tổ chức thành các thuộc tính của lớp đối tượng. Việc truy nhập đến dữ liệu phải thông qua các phương thức của đối tượng lớp.  Sử dụng lại mã nguồn: việc sử dụng lại mã nguồn được thể hiện thông qua cơ chế thừa kế. Cơ chế này cho phép các lớp đối tượng có thể thừa kế từ các lớp đối tượng khác. Khi đó, trong các lớp dẫn xuất, có thể sử dụng các phương thức (mã nguồn) của các lớp cơ sở mà không cần phải định nghĩa lại. Lập trình hướng đối tượng có một số ưu điểm nổi bật:  Không còn nguy cơ dữ liệu bị thay đổi tự do trong chương trình vì dữ liệu đã được đóng gói vào các đối tượng. Nếu muốn truy nhập vào dữ liệu phải thông qua các phương thức được cho phép của đối tượng.  Khi thay đổi cấu trúc dữ liệu của một đối tượng, không cần thay đổi mã nguồn của các đối tượng khác, mà chỉ cần thay đổi một số thành phần của đối tượng dẫn xuất. Điều này hạn chế sự ảnh hưởng xấu của việc thay đổi dữ liệu đến các đối tượng khác trong chương trình.  Có thể sử dụng lại mã nguồn, tiết kiệm tài nguyên, chi phí thời gian vì nguyên tắc thừa kế cho phép các lớp dẫn xuất sử dụng các phương thức từ lớp cơ sở như những phương thức của chính nó, mà không cần thiết phải định nghĩa lại.  Phù hợp với các dự án phần mềm lớn, phức tạp. 1.4.3. Cách viết dòng ghi chú Trong một chương trình cần thiết có các lời chú thích, ngoài cách viết các lời chú thích như trong C, trong C++ ta sử dụng // để viết lời chú thích trên một dòng. Mọi Trang - 11 -
  12. LËp tr×nh h-íng ®èi t-îng ký hiệu đi sau “//” cho đến hết dòng được coi là chú thích, được chương trình dịch bỏ qua khi biên dịch chương trình. Ví dụ: cin>>n; //nhap gia tri cho n tu ban phim 1.4.4. Khai báo linh hoạt và hằng có kiểu Trong C++ không nhất thiết phải nhóm lên đầu các khai báo đặt bên trong một hàm hay một khối lệnh, mà có thể đặt xen kẽ với các lệnh xử lý. Ví dụ 1.1: #include #include void main() { int x,y; coutx; couty; int tong ; tong = x+y; cout
  13. LËp tr×nh h-íng ®èi t-îng 1.4.5. C¸c kiÓu char vµ int Trong C mét h»ng ký tù ®-îc xem lµ nguyªn do ®ã nã cã kÝch th-íc b»ng 2 byte. Cßn trong C++ mét h»ng ký tù ®-îc xem lµ gi¸ trÞ kiÓu char vµ cã kÝch th-íc b»ng mét byte. Nh- vËy, trong C++ th× sizeof(„ A‟ ) = sizeof(char) = 1 1.4.6. LÊy ®Þa chØ c¸c phÇn tö m¶ng thùc hai chiÒu Ng«n ng÷ lËp tr×nh C kh«ng cho phÐp dïng to¸n tö & ®Ó lÊy ®Þa chØ phÇn tö m¶ng thùc hai chiÒu. V× vËy, khi nhËp gi¸ trÞ cho phÇn tö m¶ng thùc hai chiÒu ph¶i sö dông mét biÕn phô cã kiÓu thùc. Tr-íc tiªn ta nhËp gi¸ trÞ cho biÕn phô, sau ®ã, ta lÊy gi¸ trÞ biÕn phô ®ã ®Ó g¸n cho phÇn tö m¶ng thùc cÇn nhËp. VÝ dô 1.3: trong C ta viÕt: void nhap(float A[20][20], int n) { float x; for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) { printf(“ A[%d][%d] = “ ,i+1, j+1) scanf(“ %f” , &x); A[i,j] = x; } } C++ cho phÐp lÊy ®Þa chØ m¶ng thùc hai chiÒu sö dông to¸n tö &. V× vËy, cã thÓ dïng scanf ®Ó nhËp trùc tiÕp vµo c¸c phÇn tö m¶ng. void nhap(float A[20][20], int n) { for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) { printf(“ A[%d][%d] = “ ,i+1, j+1) scanf(“ %f” , &A[i,j]); } } Trang - 13 -
  14. LËp tr×nh h-íng ®èi t-îng 1.4.7.Vào ra trong C++ Các hàm vào/ra của C đều có thể sử dụng trong C++. Để sử dụng các hàm này chúng ta chỉ cần khai báo tệp tiêu đề stdio.h trong đó có chứa khai báo hàm nguyên mẫu của chúng. Bên cạnh đó, C++ còn cài đặt thêm các khả năng vào/ra mới dựa trên hai toán tử “>>”(nhập) và “” và “
  15. LËp tr×nh h-íng ®èi t-îng 1.4.8. Cấu trúc trong C++ C++ vẫn chấp nhận khai báo kiểu cấu trúc như trong C. Ngoài ra, C++ còn cho phép khai báo kiểu cấu trúc theo cú pháp: struct tên_kiểu { KiÓu_dl Tr-êng_1; KiÓu_dl Tr-êng_1; KiÓu_dl Tr-êng_1; }; mµ kh«ng cÇn ph¶i sö dông tõ kho¸ typedef nh- trong C. VÝ dô 1.5: struct product { int weight; float price; }; product apple; product banana, melon; 1.4.9. Cấp phát bộ nhớ trong C++ Ngoài các hàm cấp phát bộ nhớ như malloc, realloc, calloc như trong C, C++ cung cấp toán tử new để cấp phát bộ nhớ và toán tử delete để giải phóng bộ nhớ được cấp phát bởi toán tử new. Toán tử new thay thế cho hàm malloc() hay calloc() của C, có cú pháp như sau: new Kiểu_dữ_liệu Nếu kiểu dữ liệu mô tả phức tạp, nó có thể được đặt bên trong các dấu ngoặc. Nếu toán tử new cấp phát không thành công thì nó sẽ trả về giá trị NULL. Chúng ta có thể vừa cấp phát vừa khởi động như sau : Con_trỏ = new Kiểu_dl(Giá_trị); Ví dụ 1.6: int *P; P = new int(100); Toán tử delete thay thế hàm free() của C, nó có cú pháp như sau : delete Con_trỏ; Trang - 15 -
  16. LËp tr×nh h-íng ®èi t-îng delete [] Con_trỏ; Để cấp phát một mảng, chúng ta làm như sau : Con_trỏ = new Kiểu_dữ_liệu[Kích_thước_mảng] ; Ví dụ 1.7: int *P; P = new int[10]; //Cấp phát mảng 10 số nguyên Chú ý: Đối với việc cấp phát mảng chúng ta không thể vừa cấp phát vừa khởi gán giá trị cho chúng, chẳng hạn đoạn chương trình sau là sai : int *P; P = new (int[10])(3); //Sai !!! Ví dụ 1.8: Sử dụng kiểu cấu trúc, các toán tử new, delete trong việc cài đặt một số phép toán trên danh sách nối kép. #include #include struct node //khai bao cau truc mot nut trong ds noi kep { int info; node *lptr; node *rptr; }; node *l,*r; void create(int n)//t¹o lËp danh s¸ch nèi kÐp l-u tr÷ n sè nguyªn { node *p;int x; for(int i=1;ilptr=NULL; p->rptr=NULL; coutp->info; if(l==NULL) l=r=p; else { Trang - 16 -
  17. LËp tr×nh h-íng ®èi t-îng r->rptr=p; p->lptr=r; r=p; } } } void ht()//hiÓn thÞ c¸c sè nguyªn trong danh s¸ch { node *p; p=l; while(p!=NULL) { coutrptr; return p; } void insert(node *m,int x) //bæ sung nót cã info = x vµo tr-íc nót trá bëi m trong ds { node *p; p=new node; p->info=x; p->lptr=NULL; p->rptr=NULL; if((r ==NULL)&&(l==NULL)) l=r=p; else if(l==m) {p->rptr=m;m->lptr=p; l=p;} Trang - 17 -
  18. LËp tr×nh h-íng ®èi t-îng else { p->rptr=m; p->lptr=m->lptr; (m->lptr)->rptr=p; m->lptr=p; } } void del(int x)//xo¸ khái danh s¸ch nót cã info = x (nÕu cã) { node *p; p=tim(x); if(p!=NULL) { if(l==r) l=r=NULL; else if(l==p) { l=p->rptr; l->lptr=NULL;} else if (r==p) {r=p->lptr;r->rptr=NULL;} else { (p->lptr)->rptr=p->rptr; (p->rptr)->lptr=p->lptr; } delete p; } } void main() { int x,n; char tl; node *p; coutn; create(n); cout
  19. LËp tr×nh h-íng ®èi t-îng ht(); do { coutx; p=tim(x); coutx; insert(p,x); cout
  20. LËp tr×nh h-íng ®èi t-îng 1.5.2. Truyền giá trị cho hàm theo biến tham chiếu Trong C++ khi dùng đối số là biến tham chiếu sẽ làm cho hàm thao tác trực tiếp trên vùng nhớ của các tham số do đó sẽ dễ dàng thay đổi giá trị của các tham số khi cần. Ví dụ 1.10: void swap(int &x, int &y) { int temp = x; x = y; y = temp} Hàm swap đã sử dụng hai đối x, y là các biến tham chiếu. Khi đó, hàm có thể làm thay đổi giá trị của tham số thực được truyền cho hàm. Việc truyền tham số cho hàm sử dụng biến tham chiếu giống như việc truyền tham số sử dụng biến nhớ thông thường khác. Ví dụ, để gọi hàm swap ta viết: swap(a, b); 1.5.3. Hàm trả về các tham chiếu Hàm có thể trả về giá trị tham chiếu hoặc có kiểu tham chiếu. Khi đó, có thể dùng hàm để truy nhập đến một biến hoặc một phần tử mảng nào đó. Định nghĩa của hàm có giá trị trả về là tham chiếu có dạng như sau: & fct( ...) { ... return ; } Trong trường hợp này biểu thức được trả lại trong câu lệnh return phải là tên của một biến xác định từ bên ngoài hàm, bởi vì chỉ khi đó mới có thể sử dụng được giá trị của hàm. Khi trả về một tham chiếu đến một biến cục bộ khai báo bên trong hàm, biến cục bộ này sẽ bị mất đi khi kết thúc thực hiện hàm và do vậy, tham chiếu của hàm cũng không còn có ý nghĩa nữa. Khi giá trị trả về của hàm là tham chiếu, ta có thể gặp các câu lệnh gán “kỳ dị” trong đó vế trái là một lời gọi hàm chứ không phải là tên của một biến. Điều này hoàn toàn hợp lý, bởi lẽ bản thân hàm đó có giá trị trả về là một tham chiếu. Nói cách khác, vế trái của lệnh gán (biểu thức gán) có thể là lời gọi đến một hàm có giá trị trả về là một tham chiếu. Ví dụ 1.11: Trang - 20 -
nguon tai.lieu . vn