Bài giảng Lập trình C/C++ - Chương 10: Lập trình hướng đối tượng (Cơ bản) - Lê Thành Sách
Nội dung
n Kiểu dữ liệu trong C - Ôn lại
n Các khái niệm cơ bản
n Con trỏ this
n Tổng hợp các thuật ngữ (I)
n Tính khả kiến
n Thiết kế lớp
n Hàm khởi tạo và hàm huỷ
n Định nghĩa lại toán tử
n Thành viên có tính “static”
n Thành viên có tính “const”
n Tổng hợp các thuật ngữ (II)
n Quan hệ bạn bè (friendship)
n Tổ chức mã nguồn cho lớp
n Biễu diễn lớp bằng sơ đồ
n Tổng kết
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình C/C++ - Chương 10: Lập trình hướng đối tượng (Cơ bản) - Lê Thành Sách", để tải tài liệu gốc về máy hãy click vào nút Download ở trên
Tóm tắt nội dung tài liệu: Bài giảng Lập trình C/C++ - Chương 10: Lập trình hướng đối tượng (Cơ bản) - Lê Thành Sách
Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 1 Chương 10 Lập trình hướng đối tượng --Cơ bản-- Lê Thành Sách CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 2 Nội dung n Kiểu dữ liệu trong C - Ôn lại n Các khái niệm cơ bản n Con trỏ this n Tổng hợp các thuật ngữ (I) n Tính khả kiến n Thiết kế lớp n Hàm khởi tạo và hàm huỷ n Định nghĩa lại toán tử n Thành viên có tính “static” n Thành viên có tính “const” n Tổng hợp các thuật ngữ (II) n Quan hệ bạn bè (friendship) n Tổ chức mã nguồn cho lớp n Biễu diễn lớp bằng sơ đồ n Tổng kết CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 3 typedef struct{ int day, month, year; } Date; int main(int argc, char** argv) { int a; double d; Date c = {20, 5, 2017}; return 0; } Kiểu dữ liệu trong C n Xét đoạn chương trình Bộ biên dịch cấp phát 3 vùng nhớ có tên: a, d, và c trên STACK: a: 4 bytes à dùng sizeof(.) cho cụ thể. d: 8 bytes c: 12 bytes Cả 3 vùng nhớ này đều THỤ ĐỘNG, CHỈ CÓ CÔNG NĂNG LÀ CHỨA các giá trị của kiểu được mô tả. CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 4 Kiểu dữ liệu trong C Vì thụ động, nên khi cần xử lý dữ liệu, thực hiện: a) Tạo ra hàm b) Gọi hàm và truyền dữ liệu vào à Ví dụ như hàm: “print” ở trên typedef struct{ int day, month, year; } Date; void print(Date& d){ cout << d.day << "/" << d.month << "/" << d.year; } int main(int argc, char** argv) { int a; double d; Date c = {20, 5, 2017}; print(c); return 0; } CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 5 Kiểu dữ liệu trong C Vì thụ động, nên khi cần xử lý dữ liệu: a) Tạo ra hàm b) Gọi hàm và truyền dữ liệu vào à Ví dụ như hàm: print ở trên Nhược điểm của tính THỤ ĐỘNG này là gì? typedef struct{ int day, month, year; } Date; void print(Date& d){ cout << d.day << "/" << d.month << "/" << d.year; } int main(int argc, char** argv) { int a; double d; Date c = {20, 5, 2017}; print(c); return 0; } CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 6 Kiểu dữ liệu trong C n Nhược điểm là gì? n Khó biết được dữ liệu có thể được xử lý bởi hàm nào. n Khó đảm bảo ràng buộc trên dữ liệu, ví dụ: n Ngày: 1 à 31 (tuỳ tháng, tối đa) n Tháng: 1 à 12 Chỉ cần tính chất về “đóng gói” (enscapsulation) của lập trình hướng đối tượng (OOP) đã giải quyết những vấn đề trên. Hơn nữa, ngoài tính “đóng gói”, OOP còn cung cấp những tính năng hay khác nữa mà ngôn ngữ C không có. CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 7 Khái niệm cơ bản n (Q.1) Lớp (class): n Là một kiểu dữ liệu do người lập trình tạo ra. n Quan niệm: Lớp như cái khuôn để từ đó tạo ra các đối tượng như nói sau. n (Q.2) Đối tượng (object, instance): n Là một biến tạo ra từ kiểu lớp. n Ví dụ: n Giả sử đã có lớp MyClass n Dòng: MyClass c; n Sẽ tạo ra một đối tượng, đặt tên là “c”, nghĩa là một vùng nhớ có tên là “c”. CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 8 Khái niệm cơ bản n (Q.3) Mô tả lớp có gì khác mô tả một cấu trúc trong C (struct) n Khi mô tả kiểu này, cần mô tả n Các dữ liệu mà một đối tượng của lớp có. n Các hàm (phương thức) có thể thực thi với đối tượng của lớp. n Những hành động mà một đối tượng của lớp đó có thể thực hiện à tính chủ động của đối tượng (không chỉ là vùng nhớ thụ động) Với kiểu struct (của C): Mô tả kiểu này không có mô tả hàm/phương thức như kiểu lớp! CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 9 Khái niệm cơ bản n (Q.4) Tạo đối tượng như thế nào? n Giống như struct. Giả sử có lớp MyClass n (1) Tạo tĩnh trên STACK: MyClass obj; MyClass obj(); //có thể truyền tham số - xem Phần Constructor n (2) Tạo động trên HEAP: MyClass *ptr = new MyClass(); MyClass *ptr = new MyClass(); //có thể truyền tham số - xem Phần Constructor //dùng ptr tại đây delete ptr; CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 10 Khái niệm cơ bản n (Q.4) Tạo đối tượng như thế nào? n Giống như struct. Giả sử có lớp MyClass n (1) Tạo tĩnh trên STACK, mảng tĩnh MyClass obj[SIZE]; n (2) Tạo động trên HEAP: MyClass *ptr = new MyClass[SIZE]; //.. sử dụng ptr delete []ptr; CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 11 Khái niệm cơ bản n (Q.5) Truy xuất dữ liệu và gọi phương thức ntn? n Giống như struct. Giả sử có lớp MyClass n (1) đối tượng trên STACK: MyClass obj; ... obj.[tên-thành-viên]; //xem ví dụ. n (2) đối tượng trên HEAP: MyClass *ptr = new MyClass(); ... Obj->[tên-thành-viên]; //xem ví dụ. Lưu ý: Toán tử chấm “.” và toán tử mũi tên “->” CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 12 Khái niệm cơ bản: Minh hoạ (I) n Tạo ra một kiểu “Date”, theo yêu cầu: n Một đối tượng của “Date” có phải chứa được dữ liệu về ngày, tháng, và năm. n Một đối tượng của “Date” có thể đón nhận lời yêu cầu “print”. Một khi nó (đối tượng) nhận được yêu cầu này, nó in ra màn hình ngày, tháng, và năm mà nó đang giữ. n Đối tượng có tính CHỦ ĐỘNG hơn so với các biến kiểu cấu trúc (của C) CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 13 Khái niệm cơ bản: Minh hoạ (I) class Date{ public: int day, month, year; void print(){ cout << day << "/" << month << "/" << year << endl; } }; Một lớp (class) “Date” Chú ý: kết thúc bằng dấu ; Mô tả dữ liệu cho đối tượng của lớp “Date” Mô tả phương thức cho đối tượng của lớp “Date”: khai báo + định nghĩa hàm CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 14 Khái niệm cơ bản: Minh hoạ (I) class Date{ public: int day, month, year; void print(){ cout << day << "/" << month << "/" << year << endl; } }; Từ khoá “public” nghĩa là gì? Cho phép bất kỳ nơi nào, miễn sao có tham chiếu đến đối tượng kiểu “Date”, là có thể dùng được các dữ liệu và phương thức theo sau “public”, i.e., day, month, year và print Xem phần “Tính khả kiến” – theo sau. CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 15 Khái niệm cơ bản: Minh hoạ (I) int main(int argc, char** argv) { Date d1 = {20, 5, 2017}; Date d2 = {21, 5, 2017}; Date d3 = {22, 5, 2017}; d1.print(); d2.print(); d3.print(); return 0; } Dùng lớp “Date” như thế nào? Xem hàm main() sau: CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 16 Khái niệm cơ bản: Minh hoạ (I) int main(int argc, char** argv) { Date d1 = {20, 5, 2017}; Date d2 = {21, 5, 2017}; Date d3 = {22, 5, 2017}; d1.print(); d2.print(); d3.print(); return 0; } day: month: year: 20 5 2017 print d1 day: month: year: 22 5 2017 print d3 day: month: year: 21 5 2017 print d2 Tạo ra 3 đối tượng có tên là d1, d2, và d3, và khởi gán giá trị ban đầu. Lưu ý: Đối tượng = dữ liệu + hàm CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 17 Lưu ý Trong trường hợp như lớp “Date”, phương thức “print” không phải liên kết động (vì: non-virtual) nên con trỏ hàm không cần đi kèm trong bộ nhớ cấp cho đối tượng, xem hình. Tuy nhiên, slide này trình bày mô hình như vậy để giúp sinh viên dễ dàng nắm bắt khái niệm gói cả dữ liệu và hàm. Có thể xem đây là mô hình đơn giản và ở mức cao (luận lý). Người học nên xem thêm các tài liệu khác để nắm rõ hơn về mô hình đối tượng (Object Model): [1] Stanley B. Lippman, “Inside the C++ Object Model,” Addison Wesley, 1996. [2] Tuy vậy, chỉ nên đọc sau khi nắm bắt chắc các khái niệm và cách dùng OOP trong slide này. CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 18 Khái niệm cơ bản: Minh hoạ (I) int main(int argc, char** argv) { Date d1 = {20, 5, 2017}; Date d2 = {21, 5, 2017}; Date d3 = {22, 5, 2017}; d1.print(); d2.print(); d3.print(); return 0; } day: month: year: 20 5 2017 print d1 class Date{ public: int day, month, year; void print(){ cout << day << "/" << month << "/" << year << endl; } }; Khi gọi hàm print của d1 thì: day = 20; month = 5; Và year = 2017 Lưu ý: CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 19 Khái niệm cơ bản: Minh hoạ (I) int main(int argc, char** argv) { Date d1 = {20, 5, 2017}; Date d2 = {21, 5, 2017}; Date d3 = {22, 5, 2017}; d1.print(); d2.print(); d3.print(); return 0; } Khi gọi hàm print của d2 thì: day = 21; month = 5; Và year = 2017 Lưu ý:day: month: year: 21 5 2017 print d2 class Date{ public: int day, month, year; void print(){ cout << day << "/" << month << "/" << year << endl; } }; CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 20 day: month: year: 22 5 2017 print d3 Khái niệm cơ bản: Minh hoạ (I) int main(int argc, char** argv) { Date d1 = {20, 5, 2017}; Date d2 = {21, 5, 2017}; Date d3 = {22, 5, 2017}; d1.print(); d2.print(); d3.print(); return 0; } Khi gọi hàm print của d3 thì: day = 22; month = 5; Và year = 2017 Lưu ý: class Date{ public: int day, month, year; void print(){ cout << day << "/" << month << "/" << year << endl; } }; CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 21 Khái niệm cơ bản: Minh hoạ (I) int main(int argc, char** argv) { Date d1 = {20, 5, 2017}; Date d2 = {21, 5, 2017}; Date d3 = {22, 5, 2017}; d1.print(); d2.print(); d3.print(); return 0; } Kết quả xuất ra màn hình: 20/5/2017 21/5/2017 22/5/2017 CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 22 Khái niệm cơ bản: Minh hoạ (I) int main(int argc, char** argv) { Date d1 = {20, 5, 2017}; Date d2 = {21, 5, 2017}; Date d3 = {22, 5, 2017}; d1.print(); d2.print(); d3.print(); return 0; } class Date{ public: int day, month, year; void print(){ //đã rút gọn } }; Vì từ khoá “public” à day, month, year và print có thể truy cập được bất kỳ đâu. è Truy cập được trong hàm main() CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 23 Con trỏ “this” n Đối tượng = dữ liệu + hàm. Ví dụ: n Địa chỉ đến (byte đầu tiên của) đối tượng được lưu trong biến “this” (là từ khoá). Địa chỉ này chỉ có thể dùng được bên trong các hàm thành viên của đối tượng. n Bên trong print của d1: this chỉ đến vùng d1. n Bên trong print của d2: this chỉ đến vùng d2, ... day: month: year: 20 5 2017 print d1 day: month: year: 21 5 2017 print d2 day: month: year: 22 5 2017 print d3 CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 24 Con trỏ “this”: Minh hoạ (I) class Date{ public: int day, month, year; void print(){ cout << day << "/" << month << "/" << year << endl; } }; class Date{ public: int day, month, year; void print(){ cout day month year << endl; } }; Hàm print có thể viết như sau: CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 25 Con trỏ “this”: Minh hoạ (II) class Date{ public: int day, month, year; void print(){ //đã rút gọn } void setDay(int day){ } }; Tại đây có hai biến cùng tên: day. • day: của thông số • Và, day là thành viên của lớp. Mặc nhiên, day của thông số là ưu tiên. Do đó, để gán day của thông số vào day thành viên thì dùng “this”, như sau: this->day = day; CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 26 Con trỏ “this”: Minh hoạ (III) class Date{ public: int day, month, year; void print(){ //đã rút gọn } void setDay(int day){ this->day = day; } Date& getDate(){ } }; Giả sử: cần trả về tham khảo đến đối tượng đang chứa hàm getDate Làm như thế nào? Dùng con trỏ “this”, như sau: return *this; CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 27 Con trỏ “this”: Minh hoạ (IV) class Date{ public: int day, month, year; void print(){ //đã rút gọn } void setDay(int day){ this->day = day; } Date& getDate(){ return *this; } Date* getDatePtr(){ } }; Giả sử: cần trả về con trỏ đến đối tượng đang chứa hàm getDatePtr Làm như thế nào? Dùng con trỏ “this”, như sau: return this; CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 28 Con trỏ “this”: Câu hỏi class Date{ public: int day, month, year; void print(){ //đã rút gọn } void setDay(int day){ this->day = day; } Date& getDate(){ return *this; } Date* getDatePtr(){ return this; } }; int main(){ Date d; cout << ”ptr1:" << hex << &d << endl; cout << ”ptr2: " << hex << d.getDatePtr() << endl; return 0; } Giá trị in ra chỗ ptr1 và ptr2 có bằng nhau? CuuDuongThanCong.com https://fb.com/tailieudientucn ... int rs; rs = const_value + nonconst_value; //const_value = 100; //nonconst_value = 100; mutable_value = 100; rs += mutable_value; return rs; } }; Nếu hai dòng này được biên dịch à lỗi biên dịch. Lý do: phương thức có tính hằng chỉ có thể thay đổi biến có tính “mutable”. CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 94 Thuật ngữ (II) n Tổng kết các khái niệm quan trọng: Tiếng việt Tiếng Anh Chú thích Lớp class Xem như một kiểu dữ liệu Đối tượng Object, instance Xem như một biến Thuộc tính; Biến thành viên; Trường dữ liệu; Thành viên dữ liệu Attribute; Member variable; Data field; Data member Dữ liệu + Phương thức được gói lại thành đối tượng (gói dữ liệu và địa chỉ hàm)Phương thức; Hàm thành viên; Hành xử; Hành động Method; Function member; Behavior; operation CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 95 Thuật ngữ (II) n Tổng kết các khái niệm quan trọng: Tiếng việt Tiếng Anh Chú thích Tính khả kiến Visibility Cho biết một thuộc tính & phương thức có thể dùng được ở đâu trong mã nguồn (lớp nào, phương thức nào, hàm nào?) Ba tính khả kiến: public, private, và protected public, private, và protected public: mọi nơi private: của riêng protected: của riêng + dành cho con và cháu. Hàm đọc dữ liệu getter Nên: • Các thuộc tính có tính khả kiến là: private • Mỗi thuộc tính nên kèm theo 01 getter và 01 setter. Hàm ghi dữ liệu setter CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 96 Thuật ngữ (II) n Tổng kết các khái niệm quan trọng: Tiếng việt Tiếng Anh Chú thích từ khoá “this” this this: có kiểu là địa chỉ. this: chứa địa chỉ đến byte đầu tiên của vùng nhớ của đối tượng. this: chỉ được nhìn thấy bên trong các hàm thành viên. è this->data_member; this->foo(); với: data_member: thuộc tính foo(): một phương thức của đối tượng. CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 97 Thuật ngữ (II) n Tổng kết các khái niệm quan trọng: Tiếng việt Tiếng Anh Chú thích Hàm khởi tạo copy Copy constructor Khi biến thành viên được cấp phát động (như ma trận ở slide trước) CẦN PHẢI: èĐịnh nghĩa lại cả “copy contructor” và “copy assignment” Phép gán Copy assignment CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 98 Quan hệ bạn bè (friendship) n Giả sử lớp ClassA và ClassB là hai lớp độc lập, không có quan hệ thừa kế (sẽ trình bày sau) n Các phương thức thành viên của ClassA không thể truy cập các thành viên (biến & hàm) có tính private và protected của ClassB và ngược lại. n Trong dự án có một số lớp cần cho các lớp khác truy xuất các thành viên (biến & hàm) có tính private và protected của nó. Vì lý do: n Code cho đơn giản. n Tránh gọi hàm nhiều lần à chạy nhanh hơn. n Các lớp này được thiết kế cẩn thận và nằm trong cùng dự án nên vẫn có thể kiểm soát sự toàn vẹn dữ liệu được. CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 99 Quan hệ bạn bè (friendship) n Các dạng friendship n Hàm friend n Cho phép một hàm không phải thành viên của lớp ClassX vẫn có thể truy cập các thành viên (biến & hàm) có tính private và protected của ClassX. n Lớp friend n Cho phép tất cả các hàm thành viên của ClassY có thể truy cập các thành viên (biến & hàm) có tính private và protected của ClassX. CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 100 Quan hệ bạn bè (friendship): Minh hoạ (I) n Hàm friend: n Với lớp Matrix ở các slide trước, hãy bổ sung code để cho phép người lập trình có thể thực hiện các phép toán sau: n Cho phép người lập trình nhập và xuất ma trận bằng các toán tử: > n Cộng/trừ/nhân/chia một số vô hướng (số thực, double) với ma trận, như ví dụ sau. Ý nghĩa của các phép toán này là thực hiện phép toán đó giữa số vô hướng với từng phần tử của ma trận double data[] = {1,2,3,4,5,6}; Matrix m1(2,3, data, 6); Matrix m2, m3, m4; m2 = 3.5 + m1; m3 = 3.5 - m1; m4 = 3.5 * m1; m5 = 3.5 / m1; CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 101 Quan hệ bạn bè (friendship): Minh hoạ (I) n Phân tích: n Prototype của các toán tử như sau: n Với dạng protoype như vậy, chúng không thể là hàm thành viên của lớp Matrix. n Nhưng, chúng ta truy xuất các dữ liệu: số hàng, số cột, và dữ liệu (có tính private) của Matrix n è Dùng Hàm friend § ostream &operator<<( ostream &output, const Matrix& matrix); § istream &operator>>( istream &input, Matrix& matrix); § Matrix operator+(double value, const Matrix& matrix); § Matrix operator-(double value, const Matrix& matrix); § Matrix operator*(double value, const Matrix& matrix); § Matrix operator*(double value, const Matrix& matrix); CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 102 Quan hệ bạn bè (friendship): Minh hoạ (I) class Matrix{ public: friend ostream &operator<<( ostream &output, const Matrix& matrix); friend istream &operator>>( istream &input, Matrix& matrix); friend Matrix operator+(double value, const Matrix& matrix); friend Matrix operator-(double value, const Matrix& matrix); friend Matrix operator*(double value, const Matrix& matrix); friend Matrix operator*(double value, const Matrix& matrix); // Các hàm thành viên khác, xem các slide trước. private: double *m_data_ptr; int m_nrows, m_ncols; }; Khai báo hàm (toán tử) friend CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 103 Quan hệ bạn bè (friendship): Minh hoạ (I) istream &operator>>( istream &input, Matrix& matrix){ // Các lệnh nhập dữ liệu tại đây return input; } Định nghĩa toán tử >> ostream &operator<<( ostream &output, const Matrix& matrix){ // Các lệnh xuất dữ liệu tại đây return output; } Định nghĩa toán tử << CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 104 Quan hệ bạn bè (friendship): Minh hoạ (I) Matrix operator+(double value, const Matrix& matrix){ Matrix rs = matrix; //Cộng các phần tử của rs với value, gán lại vào rs. return rs; } Matrix operator-(double value, const Matrix& matrix){ Matrix rs = matrix; //Trừ value cho các phần tử của rs, gán lại vào rs. return rs; } Định nghĩa toán tử + và – Các toán tử * và / tương tự. CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 105 Quan hệ bạn bè (friendship): Minh hoạ (II) n Lớp friend: n Với lớp Matrix ở các slide trước, giả sử cần thiết kế lớp xử lý dữ liệu (DataProcessor). n Lớp DataProcessor có nhiều hàm thành viên, chúng cần lưu dữ liệu dưới dạng ma trận, và chúng cần truy xuất dữ liệu của ma trận (số hàng, số cột, và dữ liệu các phần tử). n => Có thể sử dụng lớp friend để cho phép tất cả các phương thức trong DataProcessor truy xuất được các dữ liệu liệu của ma trận (có tính private). n Khai báo lớp DataProcessor là friend của lớp Matrix như sau. CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 106 Quan hệ bạn bè (friendship): Minh hoạ (I) Class DataProcessor; //Khai báo trước cho lớp DataProcessor class Matrix{ public: friend class DataProcessor; friend ostream &operator<<( ostream &output, const Matrix& matrix); friend istream &operator>>( istream &input, Matrix& matrix); friend Matrix operator+(double value, const Matrix& matrix); // Các hàm thành viên khác, xem các slide trước. private: double *m_data_ptr; int m_nrows, m_ncols; }; Khai báo lớp friend Chú ý cả dòng khai báo trước cho lớp DataProcessor à để danh hiệu DataProcessor được biết là một lớp Lớp DataProcessor: không có gì đặc biệt khi kết hợp vói friend CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 107 Tổ chức mã nguồn cho các lớp n Một lớp có nhiều hàm thành viên, phần thân những hàm này có thể để chung với phần mô tả của lớp, như ở các ví dụ trước. n Tuy vậy, thường các dự án lớn (đặc biệt là dạng thư viện phần mềm), mỗi lớp được tổ chức thành 2 tập tin riêng biệt: n Tập tin header (*.h): n Tập tin này chứa phần mô tả (description, declaration) cho lớp n Tập tin source (*.cpp): n Tập tin này chứa phần định nghĩa (definition) cho lớp CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 108 Tổ chức mã nguồn: Minh hoạ #ifndef DATE_H #define DATE_H class Date{ public: int getDay(void); void setDay(int newDay); int getMonth(void); void setMonth(int newMonth); int getYear(void); void setYear(int newYear); int compareTo(const Date& aDate); int distanceTo(const Date& aDate); Date(); Date(const Date& oldDate); void date(int day, int month, int year); private: int day; int month; int year; }; #endif Date.h Date.h: Chứa phần mô tả (khai báo) cho lớp CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 109 #include "Date.h" int Date::getDay(void){ return day; } void Date::setDay(int newDay){ day = newDay; } int Date::getMonth(void){ return month; } void Date::setMonth(int newMonth){ month = newMonth; } int Date::getYear(void){ return year; } void Date::setYear(int newYear){ year = newYear; } Tổ chức mã nguồn: Minh hoạ Date.cpp - PART I Date.cpp: Chứa phần định nghĩa (definition) cho lớp Dùng toán tử :: khi hàm định nghĩa bên ngoài phần mô tả của lớp. Các hàm có tên đầy đủ là: :: Như ví dụ: Date::setDay CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 110 Tổ chức mã nguồn: Minh hoạ int Date::compareTo(const Date& aDate){ // TODO : implement } int Date::distanceTo(const Date& aDate){ // TODO : implement } Date::Date(){ } Date::Date(const Date& oldDate){ day = oldDate.day; month = oldDate.month; year = oldDate.year; } Date::Date(int day, int month, int year){ // TODO : implement } Date.cpp - PART II CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 111 Biễu diễn lớp bằng sơ đồ Các thuộc tính, mỗi thuộc tính kiểu kèm theo, bên phải • Ký hiệu ổ khoá (+): tính private • Ký hiệu chìa khoá (-): tính protected • Để trống (#): tính public CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 112 Biễu diễn lớp bằng sơ đồ Các hàm thành viên, mỗi hàm có 3 cột • Cột trái: thông tin bổ sung, ví dụ: setter/getter, constructor • Cột tên hàm và danh sách thông số • Cột kiểu trả về CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 113 Biễu diễn lớp bằng sơ đồ Thông tin từ hình ảnh là tương đương với thông tin của tập tin header. Từ hình ảnh có thể sinh ra hai tập tin header và source tương ứng, chỉ có một số hàm là có thể sinh ra được phần thân, như: setter/getter và constructors CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 114 Tổng kết n Hướng đối tượng là một phương pháp để phát triển ứng dụng có nhiều ưu điểm: n Dễ cho thiết kế, viết mã, bảo trì và nâng cấp n Dễ cho quản lý dự án khi quy mô của nó lớn n Nhược điểm: n Khó hiểu lúc bắt đầu n Điểm quan trọng trong phần vừa qua: n (1) Quan điểm về đối tượng: n Đối tượng có tính chủ động. n Nó chứa dữ liệu riêng n Nó có thể đón nhận thông điệp (gọi hàm) từ các đối tượng khác. n (2) Thời gian sống của đối tượng: CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 115 Tổng kết n Điểm quan trọng trong phần vừa qua: n (2) Thời gian sống của đối tượng: n Từ thời điểm nó sinh ra: n Hàm khởi tạo luôn luôn được gọi tại thời điểm này n Đến thời điểm nó bị huỷ (ra khỏi tầm vực hoặc bị delete) n Hàm huỷ luôn luôn được gọi tại thời điểm này. n (3) Trong thời gian nó sống (lưu trong bộ nhớ) n Các đối tượng khác có thể gửi thông điệp (gọi hàm) đến nó. n Nó thực thi hàm được gọi, có thể tạo ra các đối tượng khác và nhờ các đối tượng khác thực hiện một phần việc. n Thiết kế tốt: ít khi cho các đối tượng khác trực tiếp truy xuất dữ liệu của đối tượng đang giữ mà không thông qua các phương thức. CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 116 Tổng kết n Điểm quan trọng trong phần vừa qua: n (6) Phương pháp lập trình hướng đối tượng có tính trừu tượng hoá cao (abstraction). n Hãy dùng tính khả kiến để che đi các phương thức hỗ trợ nội bộ và che đi dữ liệu nội bộ trong lớp. n Hãy chỉ chia sẽ ra bên ngoài những phương thức chọn lọc thực sự phù hợp với lớp đang được thiết kế. n à Người bắt đầu học về lập trình hướng đối tượng gặp khó khăn trong nguyên tắc thiết này à luyện tập dần dần. n (7) Biểu diễn các lớp bằng sơ đồ giúp việc nắm bắt toàn bộ dự án dễ dàng hơn. n Người bắt đầu có thể chưa quen. CuuDuongThanCong.com https://fb.com/tailieudientucntt Trường Đại Học Bách Khoa Tp.HCM Khoa Khoa học và Kỹ thuật Máy tính © 2017 Lập trình C/C++ 117 Tổng kết n Điểm quan trọng trong phần vừa qua: n (4) Quan niệm về lớp vs đối tượng n Lớp (class) như cái khuôn n Còn đối tượng như những cái bánh tạo với khuôn đó. n Dĩ nhiên, khuôn tròn, bánh không thể méo! n (5)Tổ chức mã nguồn tốt, sẽ n Tách riêng phần khai báo (hay mô tả) lớp vào một tập tin (*.h) n Tách riêng phần định nghĩa các phương thức vào tập tin hiện thực (*.cpp) n Module *.cpp (file cpp) phụ thuộc vào module *.h của chính lớp đó à dùng #include. CuuDuongThanCong.com https://fb.com/tailieudientucntt
File đính kèm:
- bai_giang_lap_trinh_cc_chuong_10_lap_trinh_huong_doi_tuong_c.pdf