Professional Documents
Culture Documents
Chương 1 - C++ Và Hướng Đối Tượng
Chương 1 - C++ Và Hướng Đối Tượng
Chương 1 - C++ Và Hướng Đối Tượng
VỚI C++
Giáo viên: Đậu Anh Tú
Chương 1: Lập trình hướng đối tượng và những mở rộng giữa của C++ so với C
Chương 2: Lớp và Đối tượng
Chương 3: Hàm bạn, Lớp bạn
Chương 4: Nạp chồng toán tử và hàm
Chương 5: Đóng gói và trừu tượng
Chương 6: Kế thừa
Chương 7: Đa hình
Chương 8: Một số vấn đề khác
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 thực hiện từ đầu đến cuối. Cách viết
chương trình như thế này 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 càng phức tạp và lớn hơn rất
nhiều. Đến lúc này phương pháp lập trình tuyến tính tỏ ra kém hiệu quả và có những trường hợp
người lập trình không thể kiểm soát được chương trình
Phương pháp lập trình cấu trúc (LTCT) ra đời theo cách tiếp cận mới, các chương trình được tổ chức
thành chương trình con, mỗi chương trình con lại có thể chia nhỏ thành các chương trình nhỏ hơn
Các chương trình con tương đối độc lập với nhau, do đó có thể phân công cho từng nhóm đảm nhận
viết các chương trình con khác nhau
Tuy nhiên, khi sử dụng phương pháp lập trình này vẫn còn gặp một khó khăn lớn là tổ chức dữ liệu
của hệ thống như thế nào trong máy tính. Bởi vì theo quan điểm của LTCT thì: Chương trình = Cấu
trúc dữ liệu + Giải thuật. Để làm được việc này đòi hỏi người lập trình phải có kiến rất vững vềcấu
trúc dữ liệu. Một khó khăn nữa gặp phải là giải thuật của chương trình phụ thuộc rất chặt chẽ vào cấu
trúc dữ liệu, do vậy chỉ cần một sự thay đổi nhỏ ở cấu trúc dữ liệu cũng có thể làm thay đổi giải thuật
và như vậy phải viết lại chương trình.
Một phương pháp lập trình mới ra đời để khắc phục nhược điểm này và đó chính là phương pháp lập
trình hướng đối tượng (LTHĐT). Điểm căn bản của phương pháp này là thiết kế chương trình xoay
quanh dữ liệu của hệ thống. Nghĩa là lúc này các thao tác xử lý của hệ thống được gắn liền với dữ
liệu và như vậy một sự thay đổi nhỏ của dữ liệu chỉ ảnh hưởng đến các một số nhỏ các hàm xử lý liên
quan.
Một ưu điểm nữa có ở phương pháp LTHĐT là cách tiếp cận bài toán trở nên gần gũi với thực tế hơn.
Lập trình hướng đối tượng (Object Oriented Programming – OOP) là một trong những kỹ thuật lập trình rất
quan trọng và sử dụng nhiều hiện nay. Hầu hết các ngôn ngữ lập trình hiện nay như Java, PHP, .NET, Ruby,
Python, C++… đều hỗ trợ OOP.
Lập trình hướng đối tượng đặt trọng tâm vào đối tượng, yếu tố quan trọng trong quá trình phát triển chương trình
và không cho phép dữ liệu biến động tự do trong hệ thống. Dữ liệu được gắn chặt với các hàm thành các vùng
riêng mà chỉ có các hàm đó tác động lên và cấm các hàm bên ngoài truy nhập tới một cách tuỳ tiện.
Trở thành một trong những phương pháp lập trình có tầm quan trọng lớn và được sử dụng phổ biến bởi vì OOP
sở hữu nhiều đặc điểm nổi bật như sau:
o Code OOP có thể sử dụng lại nên giúp cho các lập trình viên tiết kiệm được tài nguyên.
o OOP mô hình hóa được những thứ phức tạo dưới dạng các cấu trúc đơn giản.
o OOP giúp quá trình sửa lỗi trở nên dễ dàng hơn, so với việc tìm lỗi ở nhiều vị trí khác trong code thì tìm lỗi ở trong các
lớp sẽ đơn giản và ít mất thời gian hơn.
o OOP có tính bảo mật cao, có khả năng bảo vệ mọi thông tin thông qua việc đóng gói.
Đậu Anh Tú _ Cpp
o Sử dụng OOP rất dễ dàng mở rộng được dự án.
1.1.2 Lập trình hướng đối tượng
LTHĐT cho phép chúng ta phân tích bài toán thành các thực thể được gọi là các đối tượng và sau đó
xây dựng các dữ liệu cùng các hàm xung quanh các đối tượng đó. Các đối tượng có thể tác động, trao
đổi thông tin với nhau thông qua cơ chế thông báo (message).
Lớp (class)
o Có thể hiểu là định nghĩa chung cho 1 tập dữ liệu có những đặc điểm chung
Đối tượng (object)
o Có thể hiểu là 1 ví dụ cụ thể cho định nghĩa chung ở trên
C++ :là một loại ngôn ngữ lập trình bậc trung (middle-level). Đây là ngôn ngữ lập
trình đa năng được tạo ra bởi Bjarne Stroustrup như một phần mở rộng (đáng kể)
của ngôn ngữ lập trình C, hoặc "C với các lớp Class“
Ngôn ngữ đã được mở rộng đáng kể theo thời gian và C ++ hiện đại có các tính
năng: lập trình tổng quát, lập trình hướng đối tượng, lập trình thủ tục, ngôn ngữ đa
mẫu hình tự do có kiểu tĩnh, dữ liệu trừu tượng, và lập trình đa hình, ngoài ra còn
có thêm các tính năng, công cụ để thao tác với bộ nhớ cấp thấp.
C++ được thiết kế hướng tới lập trình hệ thống máy tính và phần mềm nhúng trên
các mạch vi xử lý, bao gồm cả hệ thống có tài nguyên hạn chế và tài nguyên khổng
lồ, với ưu điểm vượt trội về hiệu suất, hiệu quả và tính linh hoạt cao
C++ cho phép ta định nghĩa các phương thức khởi tạo (constructor) cho một lớp. Phương thức
khởi 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. phương thức khởi 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 phương thức khởi tạo. Để xác định phương thức khởi 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ư phương thức khởi tạo,
một lớp có thể có một phương thức 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ớ.
C++ cho phép thực hiện kế thừa 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 kế thừa cùng một lúc từ nhiều nhiều lớp khác nhau (gọi là sự đa kế thừa)
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ỗ:
o Sử dụng đơn giản.
o Kích thước bộ nhớ được rút gọn.
o 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ử.
Ngôn ngữ lập trình C chỉ hỗ trợ 1 kiểu chú thích duy nhất là chú thích theo dòng
Khác với C, C++ hỗ trợ 2 kiểu chú thích:
o Chú thích theo dòng ( // )
o Chú thích theo đoạn (/* */)
C++ hỗ trợ thêm các kiểu dữ liệu so với C như bool, wchar_t ...
Cùng với đó, C++ hỗ trợ các phép chuyển kiểu mới :static_catch, const_catch,
dynamic_catch, reinterpret_catch. Linh hoạt hơn trong từng trường hợp
C không hỗ trợ tham chiếu cho nên để quản lý 1 biến ta cần truyền địa chỉ của
biến đấy hoặc sử dụng 1 biến khác có cấp con trỏ lớn hơn biến cần quản lý 1 cấp
Ví dụ:
C++ hỗ trợ tham chiếu trực tiếp, thuận tiện cho lập trình viên
Ví dụ:
C++ hỗ trợ 2 toán tử: new, delete giúp lập trình viên dễ dàng trong việc sử dụng
vùng nhớ Heap, thay vì phải sử dụng hàm để cấp phát trong C.
Cấp phát động trong C++ cũng linh hoạt hơn khi không cần phải tính toán kích
thước của vùng nhớ.
C++ cho phép sử dụng những hàm có cùng tên (có thể khác kiểu trả về) nhưng
khác tham số truyền vào
Quy tắc nạp chồng:
o Các hàm trùng tên phải khác nhau về tham số: Số lượng, thứ tự, kiểu
Quy tắc gọi hàm:
o Tìm hàm có kiểu tham số phù hợp
o Dùng phép ép kiểu tự động
o Tìm hàm gần đúng (phù hợp) nhất
Ví dụ:
Đặt vấn đề: Khi đang lập trình, chúng ta include 2 thư viện khác nhau nhưng có 1
hàm trùng tên và tham số truyền vào với nhau nhưng xử lý của mỗi hàm là khác
nhau, vấn đề đặt ra là làm sao trình biên dịch hiểu được chúng ta đang gọi hàm nào?
Namespace sẽ giải quyết trọn vẹn vấn đề này!
Định nghĩa: Namespace là từ khóa trong C++ được sử dụng để định nghĩa một
phạm vi nhằm mục đích phân biệt các hàm, lớp, biến, ... cùng tên trong các thư viện
khác nhau.
Tại sao cần sử dụng namespace?
o Trong các project lớn, sẽ có các hàm, lớp, ... cùng tên được định nghĩa, nhưng nội
dụng khác nhau (giống như vd trên ). Trong những trường hợp này cần đặt các hàm,
lớp, ... này vào các namespace khác nhau để trình biên dịch có thể phân biệt được,
cũng như việc tường minh code cho những người cần đọc và sử dụng sau đó.
Đậu Anh Tú _ Cpp
1.3.6 Không gian tên (namespace)
Cú pháp khai báo:
Sử dụng namespace:
Ví dụ:
Trường hợp nếu cảm thấy việc gọi hàm thông qua namespace quá dài dòng và
không cần thiết, chúng ta có thể sử dụng từ khóa using để khai báo namespace
cần sử dụng cho các hàm được định nghĩa trong namespace.
Cú pháp:
Ví dụ:
Việc sử dụng namespace mục đích để nhóm các hàm liên quan với nhau và tránh
việc sử dụng hàm trùng tên.
Chúng ta có thể xây dựng nhiều namespace khác nhau phù hợp với mục đích
của lập trình viên
Các hàm không nằm trong bất kỳ namespace nào thì không cần phải khai báo
namespace khi sử dụng