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

 

pdf51 trang | Chuyên mục: C/C++ | Chia sẻ: tuando | Lượt xem: 454 | Lượt tải: 0download
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:

  • pdfbai_giang_lap_trinh_huong_doi_tuong_tap_1_chuong_2_lop_doi_t.pdf