Ngôn ngữ lập trình - Bài 04: Cấu trúc và lớp
Bạn đang xem 20 trang mẫu của tài liệu "Ngôn ngữ lập trình - Bài 04: Cấu trúc và lớp", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- ngon_ngu_lap_trinh_bai_04_cau_truc_va_lop.pdf
Nội dung text: Ngôn ngữ lập trình - Bài 04: Cấu trúc và lớp
- NGÔN NGỮ LẬP TRÌNH Bài 4: Cấu trúc và lớp Giảng viên: Lý Anh Tu ấn Email: tuanla@tlu.edu.vn
- Nội dung 1. Cấu trúc ◦ Các kiểu cấu trúc ◦ Cấu trúc là đối số hàm ◦ Khởi tạo cấu trúc 2. Lớp ◦ Định nghĩa, hàm thành viên ◦ Các thành phần public và private ◦ Hàm truy cập và hàm biến đổi 3. Hàm tạo ◦ Định nghĩa ◦ Lời gọi 4. Các công cụ khác ◦ Bổ từ const cho các tham số ◦ Hàm trực tuyến ◦ Dữ liệu thành viên tĩnh 2
- Cấu trúc Là kiểu dữ liệu gộp giống như mảng Tuy nhiên: ◦ Mảng là tập các giá trị có cùng kiểu ◦ Cấu trúc là tập các giá trị có kiểu khác nhau Định nghĩa cấu trúc: ◦ Trước khi khai báo biến ◦ Phạm vi toàn cục ◦ Không cấp phát bộ nhớ 3
- Cấu trúc Ví dụ: struct CDAccountV1 tên của kiểu cấu trúc mới { double balance; tên thành viên double interestRate; int term; }; Khai báo biến cho kiểu mới này CDAccountV1 account; ◦ Giống như khai báo các kiểu đơn giản ◦ Biến account có kiểu là CDAccountV1 ◦ Nó bao chứa các giá trị thành viên 4
- Truy cập các thành viên cấu trúc Sử dụng toán tử . để truy cập tới các thành viên ◦ account.balance ◦ account.interestRate ◦ account.term Các biến thành viên ◦ Là thành phần của biến cấu trúc ◦ Các cấu trúc khác nhau có thể có các biến thành viên cùng tên 5
- Ví dụ về cấu trúc 6
- Ví dụ về cấu trúc 7
- Ví dụ về cấu trúc 8
- Lỗi thường gặp với cấu trúc Quên dấu chấm phẩy sau định nghĩa cấu trúc struct WeatherData { double temperature; double windVelocity; }; Cần có dấu chấm phẩy! Bạn có thể khai báo các biến cấu trúc ở vị trí này 9
- Phép gán cấu trúc Cho trước một cấu trúc tên là CropYield Khai báo hai biến cấu trúc: CropYield apples, oranges; ◦ Cả hai biến là kiểu cấu trúc CropYield ◦ Cho phép thực hiện phép gán đơn giản: apples = oranges; ◦ Việc này sao chép mỗi biến thành viên của apples thành biến thành viên của oranges 10
- Cấu trúc là đối số hàm Có thể được truyền giống như các kiểu dữ liệu đơn giản ◦ Truyền giá trị ◦ Truyền tham chiếu ◦ Hoặc kết hợp Cũng có thể được trả về bởi hàm ◦ Kiểu trả về là kiểu cấu trúc ◦ Lệnh trả về trong định nghĩa hàm gửi biến cấu trúc trở về cho lời gọi 11
- Khởi tạo cấu trúc Có thể khởi tạo lúc khai báo Ví dụ: struct Date { int month; int day; int year; }; Date dueDate = {12, 31, 2003}; Khai báo cung cấp dữ liệu khởi tạo cho cả ba biến thành viên 12
- Lớp Tương tự như cấu trúc, lớp bao gồm: ◦ Các dữ liệu thành viên (giống cấu trúc) ◦ Có thêm các hàm thành viên Tích hợp cho lập trình hướng đối tượng ◦ Tập trung vào các đối tượng ◦ Đối tượng: Bao gồm dữ liệu và các thao tác ◦ Trong C++, các biến kiểu lớp là các đối tượng 13
- Định nghĩa lớp Được định nghĩa tương tự cấu trúc Ví dụ: class DayOfYear tên của kiểu lớp mới { public: void output(); hàm thành viên! int month; int day; }; Lưu ý: chỉ có nguyên mẫu của hàm thành viên, thi hành hàm nằm ở nơi khác 14
- Khai báo các đối tượng Được khai báo tương tự các biến ◦ Kiểu định nghĩa trước, kiểu cấu trúc Ví dụ: DayOfYear today, birthday; ◦ Khai báo hai đối tượng của kiểu lớp DayOfYear Các đối tượng bao gồm ◦ Dữ liệu: Các thành viên month, day ◦ Các thao tác (các hàm thành viên): output() 15
- Truy cập thành viên lớp Các thành viên được truy cập tương tự như cấu trúc Ví dụ: ◦ today.month ◦ today.day Để truy cập đến hàm thành viên: ◦ today.output(); Gọi hàm thành viên 16
- Hàm thành viên lớp Phải định nghĩa hoặc thi hành các hàm thành viên lớp Giống với các định nghĩa hàm khác ◦ Có thể đặt sau định nghĩa main() ◦ Phải chỉ rõ thuộc lớp nào VD: void DayOfYear::output() { } ◦ :: là toán tử phân giải phạm vi ◦ Nói cho trình biên dịch thành viên là từ lớp nào ◦ Tên lớp trước :: được gọi là định kiểu 17
- Định nghĩa hàm thành viên lớp Xem định nghĩa của hàm thành viên output() (trong ví dụ tiếp theo) Tham chiếu đến dữ liệu của lớp Hàm được sử dụng cho tất cả các đối tượng của lớp ◦ Tham chiếu đến dữ liệu của đối tượng đó khi được gọi ◦ VD: today.output(); //hiển thị dữ liệu của đối tượng today 18
- Ví dụ lớp hoàn chỉnh 19
- Ví dụ lớp hoàn chỉnh 20
- Ví dụ lớp hoàn chỉnh 21
- Ví dụ lớp hoàn chỉnh 22
- Vai trò của lớp Lớp là một kiểu đầy đủ: giống như các kiểu dữ liệu int, double, vân vân Biến của một kiểu lớp: được gọi là đối tượng Tham số của một kiểu lớp: có thể truyền giá trị, truyền tham biến Có thể sử dụng kiểu lớp giống như bất kỳ kiểu dữ liệu nào khác 23
- Đóng gói Kiểu dữ liệu bất kỳ bao gồm ◦ Dữ liệu (phạm vi của dữ liệu) ◦ Các thao tác (có thể được thi hành trên dữ liệu) Ví dụ: kiểu dữ liệu int có Dữ liệu: +-32,767 Các thao tác: +, -, *, /, %, so sánh, vân vân Với lớp: chúng ta chỉ ra dữ liệu, còn các thao tác phụ thuộc vào dữ liệu Đối tượng là đóng gói của giá trị giữ liệu và các thao tác trên dữ liệu 24
- Nguyên tắc lập trình hướng đối tượng Ẩn thông tin: người dùng lớp không được biết chi tiết về các thao tác làm việc như thế nào Trừu tượng dữ liệu: người dùng không được biết chi tiết về dữ liệu được vận hành như thế nào trong ATD/lớp Đóng gói: Buộc dữ liệu và các thao tác với nhau, nhưng ẩn đi các chi tiết 25
- Thành viên public và private Dữ liệu trong lớp thường được khai báo private trong định nghĩa ◦ Duy trì các quy tắc của OOP ◦ Ẩn dữ liệu với người dùng ◦ Chỉ cho phép vận hành bởi các thao tác (hàm thành viên) Các mục public (thường là các hàm thành viên) cho phép người dùng truy cập 26
- Ví dụ public và private Sửa ví dụ trước: class DayOfYear { public: void input(); void output(); private: int month; int day; }; Dữ liệu bây giờ là private Các đối tượng không thể truy cập trực tiếp public thường được đặt trước private 27
- Ví dụ public và private Sử dụng ví dụ trước Khai báo đối tượng: DayOfYear today; Đối tượng today chỉ có thể truy cập các hàm thành viên ◦ cin >> today.month; // Không được phép! ◦ cout << today.day; // Không được phép! Thay vào đó phải gọi các thao tác public ◦ today.input(); ◦ today.output(); 28
- Hàm truy cập và hàm biến đổi Đối tượng cần làm việc với dữ liệu của nó Hàm thành viên truy cập ◦ Cho phép đối tượng đọc dữ liệu ◦ Còn được gọi “hàm thành viên get” ◦ Truy hồi dữ liệu thành viên Hàm thành viên biến đổi ◦ Cho phép đối tượng thay đổi dữ liệu ◦ Thao tác dựa vào ứng dụng 29
- Tách biệt giao diện và sự thực thi Người dùng lớp không cần xem chi tiết về việc lớp được thực thi như thế nào Người dùng chỉ cần các luật ◦ Được gọi là giao diện của lớp ◦ Trong C++, bao gồm các hàm thành viên và các chú thích liên quan Sự thi hành của lớp được ẩn đi: ◦ Các định nghĩa hàm thành viên nằm ở chỗ khác ◦ Người dùng không cần thấy chúng 30
- Hàm tạo Khởi tạo các đối tượng ◦ Khởi tạo một vài hoặc tất cả các biến thành viên ◦ Cũng cho phép thực hiện các hành động khác Một kiểu hàm thành viên đặc biệt ◦ Được gọi tự động khi khai báo đối tượng Là một công cụ hữu ích ◦ Là nguyên tắc cơ bản của lập trình hướng đối tượng 31
- Định nghĩa hàm tạo Giống như các hàm thành viên khác ngoại trừ: ◦ Phải có cùng tên với tên lớp ◦ Không trả về giá trị, thậm chí là void VD: Định nghĩa lớp với hàm tạo class DayOfYear { public: DayOfYear(int monthValue, int dayValue); //Hàm tạo khởi tạo month & day void input(); void output(); private: int month; int day; } 32
- Gọi hàm tạo Khai báo đối tượng: DayOfYear date1(7, 4), date2(5, 5); Các đối tượng được tạo theo cách: ◦ Hàm tạo được gọi ◦ Các giá trị trong ngoặc được truyền như là các đối số cho hàm tạo ◦ Các biến thành viên month, day được khởi tạo: date1.month 7 date1.day 4 date2.month 5 date2.day 5 33
- Gọi hàm tạo Xét ví dụ: DayOfYear date1, date2 date1.DayOfYear(7, 4); // Không hợp lệ! date2.DayOfYear(5, 5); // Không hợp lệ! Không thể gọi hàm tạo giống như các hàm thành viên khác 34
- Định nghĩa hàm tạo Giống như các hàm thành viên khác: DayOfYear::DayOfYear(int monthValue, int dayValue) { month = monthValue; day = dayValue; } Một cách định nghĩa khác DayOfYear::DayOfYear( int monthValue, int dayValue) : month(monthValue), day(dayValue) { } ◦ Dòng thứ 3 được gọi là “phần khởi tạo” ◦ Thân để trống 35
- Nạp chồng hàm tạo Có thể nạp chồng hàm tạo giống như những hàm khác Nhắc lại: một ký hiệu bao gồm ◦ Tên hàm ◦ Danh sách tham số Cung cấp các hàm tạo với tất cả các danh sách tham số có thể có 36
- Ví dụ hàm tạo 37
- Ví dụ hàm tạo 38
- Ví dụ hàm tạo 39
- Hàm tạo không đối số Tránh nhầm lẫn với hàm chuẩn không đối số Gọi hàm chuẩn không đối số : callMyFunction(); Khai báo đối tượng không có các khởi tạo: DayOfYear date1; // Đúng! DayOfYear date(); // Sai! 40
- Gọi hàm tạo tường minh Có thể gọi lại hàm tạo sau khi đối tượng được khai báo Lời gọi như vậy tạo ra một “đối tượng vô danh”, sau đó được gán cho đối tượng hiện tại Ví dụ: DayOfYear holiday(7, 4); ◦ Hàm tạo được gọi ở thời điểm khai báo đối tượng ◦ Sau đó được khởi tạo lại: holiday = DayOfYear(5, 5); 41
- Hàm tạo mặc định Được định nghĩa là hàm tạo không đối Nên định nghĩa nó trong mọi trường hợp Được khởi tạo tự động nếu không định nghĩa hàm tạo nào Không được khởi tạo tự động nếu đã định nghĩa ít nhất một hàm tạo Nếu không có hàm tạo mặc định ◦ Không thể khai báo: MyClass myObject; 42
- Biến thành viên kiểu lớp Biến thành viên lớp có thể là một đối tượng có kiểu là một lớp khác Có một ký pháp đặc biệt: ◦ Cho phép gọi hàm tạo của đối tượng thành viên ◦ Bên trong hàm tạo của lớp phía ngoài 43
- Ví dụ biến thành viên lớp 44
- Ví dụ biến thành viên lớp 45
- Ví dụ biến thành viên lớp 46
- Ví dụ biến thành viên lớp 47
- Ví dụ biến thành viên lớp 48
- Các phương pháp truyền tham số Hiệu quả của việc truyền tham số ◦ Truyền giá trị ◦ Truyền tham biến ◦ Không khác biệt với các kiểu đơn giản ◦ Với kiểu lớp -> lợi ích rõ rệt Nên sử dụng truyền tham biến ◦ Cho dữ liệu “lớn”, chẳng hạn như kiểu lớp 49
- Bổ từ const cho các tham số Những kiểu dữ liệu lớn (chẳng hạn các lớp) ◦ Nên sử dụng phương pháp truyền tham biến ◦ Thậm chí hàm không thực hiện sửa đổi gì Bảo vệ đối số ◦ Sử dụng tham số hằng còn được gọi là tham số truyền tham biến hằng ◦ Đặt từ khóa const trước kiểu ◦ Làm cho tham số chỉ đọc ◦ Mọi nỗ lực sửa đổi sẽ dẫn đến lỗi biên dịch Áp dụng cho các tham số hàm thành viên lớp 50
- Hàm trực tuyến Với hàm không phải là hàm thành viên: ◦ Sử dụng từ khóa inline trong khai báo hàm và đầu mục hàm Với hàm thành viên lớp ◦ Đặt thi hành của hàm trong định nghĩa lớp -> trực tuyến tự động Chỉ sử dụng cho những hàm rất ngắn Mã lệnh thực sự được chèn vào nơi gọi ◦ Loại bỏ phụ phí ◦ Hiệu quả hơn, nhưng chỉ sử dụng với hàm ngắn 51
- Thành viên tĩnh Biến thành viên tĩnh ◦ Tất cả đối tượng của lớp chia sẻ một bản sao ◦ Một đối tượng thay đổi nó tất cả đều thấy sự thay đổi Sử dụng cho việc “giám sát” ◦ Một hàm thành viên có được gọi thường xuyên không ◦ Có bao nhiêu đối tượng tồn tại ở một thời điểm cho trước Đặt từ khóa static trước kiểu 52
- Hàm tĩnh Hàm thành viên có thể là tĩnh ◦ Nếu không truy cập tới dữ liệu đối tượng cần thiết ◦ Và vẫn là thành viên của lớp ◦ Làm cho nó trở thành một hàm tĩnh Có thể được gọi bên ngoài lớp ◦ Từ các đối tượng không lớp VD: Server::getTurn(); ◦ Và bởi các đối tượng lớp VD: myObject.getTurn(); Chỉ có thể sử dụng dữ liệu tĩnh, hàm tĩnh 53
- Ví dụ thành viên tĩnh 54
- Ví dụ thành viên tĩnh 55
- Ví dụ thành viên tĩnh 56
- Ví dụ thành viên tĩnh 57
- Tóm tắt Cấu trúc là một tập các kiểu khác nhau Lớp được sử dụng để kết hợp dữ liệu và hàm vào trong một đơn vị duy nhất -> đối tượng Biến thành viên và hàm thành viên ◦ Có thể là public được truy cập bên ngoài lớp ◦ Có thể là private chỉ được truy cập bên trong một định nghĩa hàm Kiểu lớp và kiểu cấu trúc có thể làm tham số cho hàm Định nghĩa lớp C++ nên tách biệt hai phần chính ◦ Giao diện: cái người dùng cần ◦ Sự thi hành: chi tiết về việc lớp thực thi 58
- Tóm tắt Hàm tạo: tự động khởi tạo dữ liệu lớp ◦ Được gọi khi khi báo đối tượng ◦ Hàm tạo có cùng tên với lớp Hàm tạo mặc định không có tham số ◦ Nên được định nghĩa trong mọi trường hợp Biến thành viên lớp có thể là đối tượng của một lớp khác Có thể trực tuyến các định nghĩa hàm rất ngắn -> thi hành hiệu quả hơn Các biến thành viên tĩnh được chia sẻ bởi các đối tượng thuộc cùng một lớp 59