Bài giảng Lập trình hướng đối tượng - Chương 2: Lớp, đối tượng và tính đóng gói
• Lớp
• Hàm tạo, hàm hủy
• Tham số của hàm tạo
• Nội tuyến tự động
• Gán đối tượng
• Truyền các đối tượng sang hàm
• Trả đối tượng từ hàm
• Hàm friend
Tóm tắt nội dung Bài giảng Lập trình hướng đối tượng - Chương 2: Lớp, đối tượng và tính đóng gói, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
ø hàm thành viên của lớp nhưng có thể truy cập các thành viên riêng của lớp. Một hàm friend được định nghiã như một hàm bình thường. Nếu nằm bên trong một lớp, hàm friend sẽ có từ khoá friend đứng trước. Hàm friend không được kế thừa từ lớp dẫn xuất (xem chương 6). • Các lợi ích khi dùng hàm friend : + sự quá tải toán tử (xem chương 5). + tạo ra các kiểu hàm nhập/xuất nào đó (xem chương 8). + tạo hàm để truy cập các thành viên riêng của hai hay nhiều lớp khác nhau. Ví dụ 8.1 // A example of a friend function. #include class myclass { int n, d; public: Chương 2 Lớp, Đối tượng và tính đóng gói 58 58 myclass(int i, int j) { n = i; d = j; } // declare a friend of myclass friend int isfactor(myclass ob) ; }; /* Here is friend function definition. It returns true if d is a factor of n. Notice that the keyword friend is not used in the definition of isfactor(). */ int isfactor(myclass ob) { if(!(ob.n % ob.d)) return 1; else return 0; } int main() { myclass ob1(10, 2), ob2(13, 3); if( isfactor(ob1) ) cout << "2 is a factor of 10\n"; else cout << "2 is not a factor of 10\n"; if( isfactor(ob2) ) cout << "3 is a factor of 13\n"; else cout << "3 is not a factor of 13\n"; return 0; } • Không thể gọi hàm friend bằng cách dùng tên đối tượng và toán tử truy cập thành viên (dấu chấm hoặc mũi tên) ob1.isfactor(); // wrong, isfactor() is not a member function • Không giống như các hàm thành viên của lớp, có thể tham chiếu trực tiếp đến các biến (riêng hoặc chung) của lớp đó, một hàm friend chỉ có thể truy cập các biến này khi liên kết với một đối tượng được khai báo trong hoặc được truyền đến cho hàm friend. Chương 2 Lớp, Đối tượng và tính đóng gói 59 59 • Một hàm friend có thể là các hàm friend của hơn một lớp. Ví dụ 8.2 #include class truck; // a forward declaration class car { int passengers; int speed; public: car(int p, int s) { passengers = p; speed = s; } friend int sp_greater(car c, truck t); }; class truck { int weight; int speed; public: truck(int w, int s) { weight = w, speed = s; } friend int sp_greater(car c, truck t); }; /* Return positive if car speed faster than truck. Return 0 if speeds are the same. Return negative if truck speed faster than car. */ int sp_greater(car c, truck t) { return c.speed - t.speed; } int main() { int t; car c1(6, 55), c2(2, 120); truck t1(10000, 55), t2(20000, 72); Chương 2 Lớp, Đối tượng và tính đóng gói 60 60 cout << "Comparing c1 and t1:\n"; t = sp_greater(c1, t1); if(t < 0) cout << "Truck is faster.\n"; else if(t == 0) cout << "Car and truck speed is the same.\n"; else cout << "Car is faster.\n"; cout << "\nComparing c2 and t2:\n"; t = sp_greater(c2, t2); if(t < 0) cout << "Truck is faster.\n"; else if(t == 0) cout << "Car and truck speed is the same.\n"; else cout << "Car is faster.\n"; return 0; } Sự tham chiếu tới (forward reference) là điều cần thiết cho trình biên dịch, do hàm sp_greater() nhận các tham số của cả hai lớp car và truck. • Một hàm có thể là thành viên của một lớp và là một hàm friend của lớp khác . Ví dụ 8.3 #include class truck; // a forward declaration class car { int passengers; int speed; public: car(int p, int s) { passengers = p; speed = s; } int sp_greater(truck t); }; class truck { int weight; int speed; public: truck(int w, int s) { weight = w, speed = s; } Chương 2 Lớp, Đối tượng và tính đóng gói 61 61 // note new use of the scope resolution operator friend int car::sp_greater(truck t); }; /* Return positive if car speed faster than truck. Return 0 if speeds are the same. Return negative if truck speed faster than car. */ int car::sp_greater(truck t) { // Since sp_greater() is member of car, only a truck object must be passed to it. return speed - t.speed; } int main() { int t; car c1(6, 55), c2(2, 120); truck t1(10000, 55), t2(20000, 72); cout << "Comparing c1 and t1:\n"; t = c1.sp_greater(t1); // evoke as member function of car if(t<0) cout << "Truck is faster.\n"; else if(t==0) cout << "Car and truck speed is the same.\n"; else cout << "Car is faster.\n"; cout << "\nComparing c2 and t2:\n"; t = c2.sp_greater(t2); // evoke as member function of car if(t<0) cout << "Truck is faster.\n"; else if(t==0) cout << "Car and truck speed is the same.\n"; else cout << "Car is faster.\n"; return 0; } Câu lệnh t = c1.sp_greater(t1); Chương 2 Lớp, Đối tượng và tính đóng gói 62 62 có thể viết đầy đủ (ít dùng) t = c1.car::sp_greater(t1); Bài tập VIII 1. Có 2 lớp pr1 và pr2 đang dùng chung một máy in. Chương trình cần biết khi nào thì máy in được dùng bởi đối tượng nào thuộc một trong hai lớp đó. Hãy tạo hàm inuse() trả về giá trị đúng khi máy in đang được dùng và giá trị sai khi ngược lại. Làm cho hàm này trở thành hàm friend của cả hai lớp pr1 và pr2. class pr1 { int printing; // ... public: pr1() { printing = 0; } void set_print(int status) { printing = status; } // ... }; class pr2 { int printing; // ... public: pr2() { printing = 0; } void set_print(int status) { printing = status; } // ... }; Chương 2 Lớp, Đối tượng và tính đóng gói 63 63 Bài tập chương 2 1. Để một đối tượng được gán vào một đối tượng khác, cần có điều kiện gì ? class samp { double *p; public: samp(double d) { p = (double *) malloc(sizeof(double)); if(!p) exit(1); // allocation error *p = d; } ~samp() { free(p); } // ... }; // ... samp ob1(123.09), ob2(0.0); // ... ob2 = ob1; Vấn đề gì sinh ra do phép gán ob1 vào ob2 ? 2. Cho lớp planet, hãy tạo hàm light() nhận một đối tượng kiểu planet làm đối số trả về một số giây cần thiết để ánh sáng đi từ mặt trời đến hành tinh. (Giả sử ánh sáng di chuyển với vận tốc 186.000 miles/second và dist_from_sun tính bằng miles) class planet { int moons; double dist_from_sun; // in miles double diameter; double mass; public: //... double get_miles() { return dist_from_sun; } }; Chương 2 Lớp, Đối tượng và tính đóng gói 64 64 3. Dùng lớp stack, hãy viết hàm loadstack() để trả về một ngăn xếp đã được nạp vào các mẫu tự alphabet (a-z). Hãy gán ngăn xếp này cho một đối tượng khác khi gọi một chương trình phụ và chứng tỏ rằng nó chứa các mẫu tự alphabet. 4. Hãy tạo lớp line để vẽ một đường trên màn hình. Lưu trữ độ dài của đường trong một biến nguyên riêng len. Hãy cho hàm tạo lưu trữ độ dài và vẽ đường bằng cách dùng dấu "*". Lập hàm hủy của line để xoá đường. 5. Hãy sửa đổi chương trình sau đây để cho mọi hàm thành viên được tự động nội truyến. class myclass { int i, j; public: myclass(int x, int y); void show(); }; myclass::myclass(int x, int y) { i = x; j = y; } void myclass::show() { cout << i << " " << j << "\n"; } int main() { myclass count(2, 3); count.show(); return 0; } Chương 2 Lớp, Đối tượng và tính đóng gói 65 65 6. Hãy tạo lớp prompt, truyền hàm tạo của lớp này một chuổi, ví dụ "Nhập vào một số nguyên : ". Cho hàm tạo hiển thị chuổi và sau đó nhận vào một số nguyên. Lưu trữ giá trị này trong một biến riêng của lớp gọi là count. Khi đối tượng có kiểu prompt bị hủy, cho chuông reng count lần. 7. Viết chương trình tạo một lớp change thực hiện việc chuyển đổi inch thành cm. Lớp change có hai biến riêng lưu trữ số inch và giá trị tương đương của nó bằng cm. Hãy truyền cho hàm tạo số inch và hiển thị số cm. Biết 1 inch = 2,54 cm 8. Cho lớp sau, viết chương trình chứng tỏ đối tượng ob được khai báo để truyền giá trị 100 cho biến a và "z" cho biến c. class sample { int a; char c; public : sample(int x, char c) { a = x; c = ch;} // ... }; 9. Dựa vào bài tập 3 chương 2, viết chương trình thực hiện hàm quá tải loadstack() nhận một số nguyên gọi là upper, làm đối số. Trong phiên bản quá tải, nếu upper = 1, hãy đưa vào ngăn xếp các ký tự in hoa. Ngược lại, đưa vào ngăn xếp các ký tự thường. 10. Dùng lớp strtype trong ví dụ 5.4 chương 2, hãy bổ sung một hàm friend, có tên get_string(), nhận con trỏ về một đối tượng kiểu strtype làm tham số và trả về con trỏ cho một chuổi được trỏ bởi đối tượng đó. 11. Cho lớp sau, hãy tạo hàm make_sum() để trả về một đối tượng kiểu summation. Hãy làm cho hàm này nhắc ngươì dùng nhập một số và sau đó tạo một đối tượng nhận giá trị này và trả nó về cho thủ tục. Viết chương trình thực hiện yêu cầu trên. 12. Trong bài tập 11 trên, hàm set_sum() đã không được định nghiã nội tuyến tự động trong khai báo lớp summation. Hãy giải thích tại sao ? Chương 2 Lớp, Đối tượng và tính đóng gói 66 66 13. Cho lớp sau đây, hãy bổ sung một hàm friend isneg() nhận một tham số loại myclass và trả về giá trị đúng nếu num là âm và giá trị sai nếu ngược lại. class myclass { int num; public : myclass(int x) { num = x;} }; 14. Một hàm friend có thể là những hàm friend của nhiều hơn một lớp được không ?
File đính kèm:
- bai_giang_lap_trinh_huong_doi_tuong_tap_1_chuong_2_lop_doi_t.pdf