Chương 2
Lớp
, Đ
ối tượng và tính đóng gói
57
57
Bài tập VII
1. Viết chương trình tạo lớp Who, cho hàm tạo của Who nhận một đối số ký tự mà
đối số này được dùng để nhận dạng một đối tượng.
Hãy cho hàm tạo hiển thò một thông báo tương tự thông báo sau đây khi tạo ra một
đối tượng :
Constructing who #x
Trong đó x là ký tự nhận dạng.
Hãy tạo hàm make_who() để trả về đối tượng Who. Hãy cho mỗi đối tượng một tên
duy nhất.
VIII/ Các hàm friend
•
Một hàm friend không phải là 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 <iostream.h>
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 <iostream.h>
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 <iostream.h>
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);