1. Trang chủ
  2. » Công Nghệ Thông Tin

Tập bài giảng Lập trình hướng đối tượng

253 8 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 253
Dung lượng 1,08 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Tập bài giảng Lập trình hướng đối tượng gồm có 5 chương với nội dung cụ thể của từng chương như sau: Chương 1: Lập trình hướng đối tượng và C++, chương 2: lớp và đối tượng, chương 3: dẫn xuất và thừa kế, chương 4: khuôn hình, chương 5: các dòng xuất nhập. Mời các bạn cùng tham khảo.

Trang 1

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 2

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 3

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 4

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 5

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 6

- 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;

Trang 7

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 8

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 9

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ự

* 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 10

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

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 11

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 12

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ý

Trang 13

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

Trang 14

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à “<<” (xuất) với các đặc tính sau đây:

- Đơn giản trong sử dụng

- Có khả năng mở rộng đối với các kiểu mới theo nhu cầu của người lập trình Trong tệp tiêu đề iostream.h người ta định nghĩa hai đối tượng cin và cout tương ứng với hai thiết bị chuẩn vào/ra được sử dụng cùng với “>>” và “<<” Thông thường ta hiểu cout là màn hình còn cin là bàn phím

Cú pháp của cout:

cout<<biểu_thức_1<<biểu_thức_2<<…<<biểu_thức_n ;

trong đó các biểu thức có thể có kiểu là các kiểu dữ liệu như : char, int, float, double, xâu ký tự

cout<<” \n” ; dùng để xuống hàng và đưa con trỏ về đầu hàng

Nếu như cout dùng để hiển thị dữ liệu ra màn hình thì cin dùng để nhập dữ liệu

từ bàn phím Có thể sử dụng cin và toán tử “>>” để nhập dữ liệu cho các biến có kiểu char, int, float, double và char * như sau:

Trang 15

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ị);

Trang 16

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 :

Trang 19

1.5.1 Biến tham chiếu

Biến tham chiếu là biến có đặc điểm:

- Không được cấp phát bộ nhớ, không có địa chỉ riêng;

- Dùng làm bí danh cho một biến nào đó và sử dụng vùng bộ nhớ của biến này

Để khai báo biến tham chiếu ta sử dụng cú pháp:

Kiểu_dữ_liệu &Biến_tham_chiếu = Biến_được_tham_chiếu;

Trong đó, biến được tham chiếu có thể là một phần tử mảng, hoặc một biến nhớ nhưng nó phải là một biến cụ thể đã tồn tại

Ví dụ 1.9:

float u,v, &r = u;

Trong ví dụ này, r là biến tham chiếu, biến được tham chiếu là biến u, hay r là bí danh của u Khi đó câu lệnh: r = r +1 sẽ tăng giá trị của biến u lên 1

Trang 20

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);

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 21

Khai bỏo một hàm f trả về tham chiếu đến một biến toàn cục z và do đú, ta cú thể dựng hàm f để truy nhập đến biến z này

1.5.5 Các hàm trực tuyến (inline)

Một hàm sẽ là hàm trực tuyến nếu có từ khóa inline tr-ớc dòng tiêu đề của hàm

Ví dụ 1.13:

inline myFunction(int n);

Trang 22

Khi sử các hàm trong một ch-ơng trình C hoặc C++ th-ờng thì phần thân hàm sau khi đ-ợc biên dịch sẽ là một tập các lệnh máy Mỗi khi ch-ơng trình gọi tới hàm, đoạn mã của hàm sẽ đ-ợc nạp vào stack để thực hiện sau đó trả về 1 giá trị nào đó nếu có và thân hàm đ-ợc loại khỏi stack thực hiện của ch-ơng trình Nếu hàm đ-ợc gọi 10 lần sẽ có 10 lệnh nhảy t-ơng ứng với 10 lần nạp thân hàm để thực hiện Với từ khoá inline chúng ta muốn gợi ý cho trình biên dịch là thay vì nạp thân hàm nh- bình th-ờng hãy chèn đoạn mã của hàm vào đúng chỗ mà nó đ-ợc gọi tới trong ch-ơng trình Điều này rõ ràng làm cho ch-ơng trình thực hiện nhanh hơn bình th-ờng Tuy nhiên inline chỉ là một gợi ý và không phải bao giờ cũng đ-ợc thực hiện hơn nữa nó làm tăng kích bộ nhớ cho ch-ơng trình Với các hàm phức tạp (chẳng hạn nh- có vòng lặp) thì không nên dùng inline mà chỉ nên dùng với các hàm đơn giản, chẳng hạn nh- các hàm chỉ thực hiện khởi tạo giá trị cho các biến

1.5.6 Định nghĩa chồng các hàm

C++ cho phép lập trình viên có khả năng viết các hàm có tên giống nhau, khả năng này đ-ợc gọi là chồng hàm (overload) Ví dụ chúng ta có thể có các hàm nh- sau:

int myFunction(int);

int myFunction(int, int);

int myFunction(int, int, int);

Các hàm overload cần thoả mãn một điều kiện là danh sách các tham số của chúng phải khác nhau (về số l-ợng tham số và hoặc kiểu tham số) Kiểu các hàm overload có thể giống nhau hoặc khác nhau Danh sách kiểu các tham số của một hàm đ-ợc gọi là chữ ký (signature) của hàm đó

Với các hàm lớn và phức tạp chúng ta nên sử dụng chồng hàm, ngoài ra việc sử dụng các hàm chồng nhau cũng làm cho ch-ơng trình sáng sủa và dễ gỡ lỗi hơn

1.5.7 Định nghĩa chồng các toán tử

C++ cho phép thực hiện các phép toán (+, -, *, /, ) trên các kiểu dữ liệu không phải kiểu dữ liệu chuẩn (đ-ợc gọi là kiểu dữ liệu ng-ời dùng tự định nghĩa) Việc khai báo các hàm thực hiện các phép toán trên kiểu dữ liệu ng-ời dùng tự định nghĩa đ-ợc gọi là định nghĩa chồng toán tử Khi đó, ta có các hàm đ-ợc gọi là hàm toán tử

Cách định nghĩa hàm toán tử:

Tên hàm: operator tiếp sau là phép toán

Trang 23

Ví dụ: operator+

Đối của hàm toán tử: Đối với toán tử hai ngôi hàm cần có hai đối, đối với toán

tử một ngôi hàm cần một đối

Ví dụ: Matran operator+(Matran x, Matran y)

Thân của hàm toán tử: Viết nh- hàm thông th-ờng

Cách gọi hàm toán tử: Có hai cách

Gọi nh- hàm thông th-ờng Ví dụ: z = operator+(a,b);

Gọi nh- cách sử dụng phép toán Ví dụ: z = x+y

cout<<” Tu so:” ; cin>>x.tuso;

do { cout<<” Mau so:” ; cin>>x.mauso; }while (x.mauso == 0);

Trang 24

kq.tuso = x.tuso*y.mauso - y.tuso*x.mauso; kq.mauso = x.mauso*y.mauso;

Trang 28

tử >> và << trên các kiểu dữ liệu do ng-ời lập trình tự định nghĩa Giả sử ta khai báo kiểu cấu trúc ts- thí sinh gồm 3 tr-ờng: sbd- số báo danh, ten- họ và tên của thí sinh, diem- tổng điểm thi của thí sinh, ta có thể sử dụng toán tử >> để nhập thông tin một thí sinh và toán tử << để hiển thị thông tin về một thí sinh, nh- trong ví dụ sau:

Trang 29

unsigned int diem;

Trang 30

}

Trang 31

Câu hỏi và Bài tập

1 Trong các khai báo con trỏ sau, những khai báo nào là đúng:

Trang 33

int add(int a, int b);

void cal(int a, int b);

int squere(int a);

khi đó, lời gọi hàm nào sau đây là đúng:

a Calcul(5, 10, add);

b Calcul(5, 10, add(2, 3));

c Calcul(5, 10, cal);

d Calcul(5, 10, squere);

10 Ta muốn cấp phát bộ nhớ cho một con trỏ kiểu int và khởi đầu giá trị cho nó là

20 Lệnh nào sau đây là đúng:

a int *pa = 20;

b int *pa = new int{20};

c int *pa = new int(20);

d int *pa = new int[20];

11 Ta muốn cấp phát bộ nhớ cho một mảng động kiểu int có chiều dài là 20 Lệnh nào sau đây là đúng:

a int *pa = 20;

b int *pa = new int{20};

c int *pa = new int(20);

d int *pa = new int[20];

Trang 35

{

char name[20];

int age;

};

khi đó, cách khai báo biến nào sau đây là đúng:

a struct Employee myEmployee;

b struct employee myEmployee;

c Employee myEmployee;

d employee myEmployee;

18 Một cấu trúc đ-ợc định nghĩa nh- sau:

typedef struct employee

c struct Employee myEmployee;

d struct employee myEmployee;

19 Với cấu trúc đ-ợc định nghĩa nh- trong bài 3 Khi đó, cách khởi tạo biến nào sau đây là đúng:

a Employee myEmployee = {„ A‟ , 27};

b Employee myEmployee = {“ A” , 27};

c Employee myEmployee = („ A‟ , 27);

d Employee myEmployee = (“ A” , 27);

20 Với cấu trúc đ-ợc định nghĩa nh- trong bài 3 Khi đó, các cách cấp phát bộ nhớ cho biến con trỏ nào sau đây là đúng:

a Employee *myEmployee = new Employee;

b Employee *myEmployee = new Employee();

c Employee *myEmployee = new Employee(10);

d Employee *myEmployee = new Employee[10];

21 Định nghĩa một cấu trúc về môn học của một học sinh có tên Subject, bao gồm các thông tin:

• Tên môn học, kiểu char[];

Trang 36

• Điểm tổng kết môn học, kiểu float;

22 Định nghĩa cấu trúc về học sinh tên là Student bao gồm các thông tin sau:

• Tên học sinh, kiểu char[];

• Tuổi học sinh, kiểu int;

• Lớp học sinh, kiểu char[];

• Danh sách điểm các môn học của học sinh, kiểu là một mảng các cấu trúc Subject

đã đ-ợc định nghĩa trong bài tập 21

• Xếp loại học lực, kiểu char[];

23 Khai báo một biến có cấu trúc là Student đã định nghĩa trong bài 22 Sau đó, thực hiện tính điểm trung bình của tất cả các môn học của học sinh đó, và viết một thủ tục xếp loại họcsinh dựa vào điểm trung bình các môn học:

• Nếu điểm trung bình nhỏ hơn 5.0, xếp loại kém

• Nếu điểm trung bình từ 5.0 đến d-ới 6.5, xếp loại trung bình

• Nếu điểm trung bình từ 6.5 đến d-ới 8.0, xếp loại khá

• Nếu điểm trung bình từ 8.0 trở lên, xếp loại giỏi

24 Viết một ch-ơng trình quản lí các học sinh của một lớp, là một dãy các cấu trúc

có kiểu Student định nghĩa trong bài 22 Sử dụng thủ tục đã cài đặt trong bài 23 để thực hiện các thao tác sau:

• Khởi tạo danh sách và điểm của các học sinh trong lớp

• Tính điểm trung bình và xếp loại cho tất cả các học sinh

• Tìm tất cả các học sinh theo một loại nhất định

25 Viết một ch-ơng trình khai báo cấu trúc phân số, xây dựng các hàm và hàm toán tử để:

Trang 37

c Tính tổng hai số phức

d Tính hiệu hai số phức

e Tính tích hai số phức

f Tính th-ơng hai số phức

27 Viết một ch-ơng trình khai báo cấu trúc Stack, xây dựng các hàm để:

a Khởi tạo Stack rỗng

b Kiểm tra Stack đầy

c Kiểm tra Stack rỗng

c Bổ sung một phần tử vào Stack

d Loại bỏ phần tử ở đỉnh Stack

Sử dụng Stack để đổi một số nguyên d-ơng từ hệ thập phân sang hệ nhị phân

28 Viết một ch-ơng trình khai báo cấu trúc ma trận vuông cấp n, xây dựng các hàm

29 Viết ch-ơng trình khai báo cấu trúc một nút (phần tử) trong danh sách nối đơn

có tr-ờng info có kiểu số nguyên và xây dựng các hàm để:

a Tạo danh sách

b Hiển thị danh sách

c Bổ sung một phần tử vào cuối danh sách

d Loại bỏ phần tử ở đầu danh sách

e Sắp xếp các phần tử của danh sách theo thứ tự tăng dần của giá trị tr-ờng info

f Tìm phần tử có giá trị tr-ờng info lớn nhất

g Tìm phần tử có giá trị tr-ờng info bằng x cho tr-ớc

30 Viết một ch-ơng trình khai báo cấu một nút (phần tử) trong danh sách nối kép

có tr-ờng info có kiểu student định nghĩa trong bài 22 và các hàm để:

a Tạo danh sách l-u trữ danh sách sinh viên

b Hiển thị danh sách

c Bổ sung một phần tử vào cuối danh sách(nút cực phải)

d Loại bỏ phần tử ở đầu danh sách(nút cực trái)

Trang 38

e S¾p xÕp c¸c phÇn tö cña danh s¸ch theo thø tù tõ tr¸i sang ph¶i gi¸ trÞ tr-êng tuæi sinh viªn t¨ng dÇn

f T×m phÇn tö cã gi¸ trÞ tr-êng tªn sinh viªn ®-îc nhËp tõ bµn phÝm

Trang 39

Ch-ơng 2: Lớp và đối t-ợng

Nội dung của ch-ơng tập trung trình bày các vấn đề sau:

 Lớp: định nghĩa lớp, thành phần của lớp, phạm vi truy xuất đến các thành phần của lớp

 Đối t-ợng: biến, mảng, con trỏ đối t-ợng

void init(int ox, int oy);

void move(int dx, int dy);

void display();

Trang 40

};

/*định nghĩa các ph-ơng thức bên ngoài khai báo lớp*/

void point::init(int ox, int oy)

{

cout<<"Ham thanh phan init\n";

x = ox; y = oy; /*x,y là các thành phần của đối t-ợng gọi ph-ơng thức*/

cout<<"Ham thanh phan display\n";

cout<<"Toa do: "<<x<<" "<<y<<"\n";

Ngày đăng: 22/11/2021, 14:27

🧩 Sản phẩm bạn có thể quan tâm