90
CHƯƠNG 4
ðỊNH NGHĨA CHỒNG TOÁN TỬ
ðịnh nghĩa chồng (overloading) là một khả năng mạnh trong C
++
vì nó cho phép
xây dựng các toán tử cần thiết trên các lớp, giúp cho chương trình ñược viết ngắn gọn
và rõ ràng hơn. Trong C
++
có thể ñịnh nghĩa chồng hầu hết các toán tử. Các toán tử
có thể ñược ñịnh nghĩa chồng như một hàm thành phần (phương thức) của lớp hoặc
như một hàm bạn của lớp. Chương này sẽ trình bày về cách ñịnh nghĩa chồng và sử
dụng các hàm toán tử trong C
++
.
§
1. VÍ DỤ TRÊN LỚP SỐ PHỨC
1.1. Xây dựng hàm bạn cộng hai số phức
Xét một lớp số phức (SP) và xây dựng một hàm bạn ñể cộng hai số phức như sau:
class SP
{
double a, b; // Phần thực, phần ảo
public:
friend SP cong(SP u1, SP u2)
{
SP u;
u.a = u1.a + u2.a ;
}
void main()
{
SP u, v, u1, u2, u3, u4;
u= u1.cong(u2); // u là tổng u1+u2
v= u1.cong(u2.cong(u3.cong(u4))); // v là tổng u1+u2+u3+u4
}
Nhận xét:
Với cả hai cách trên (dùng hàm bạn và dùng phương thức của lớp), biểu thức sẽ
phức tạp hơn nếu có nhiều phép toán số phức (như tính v trong ví dụ trên).
C
++
cho ta một công cụ ñể giải quyết vấn ñề này: ñó là khả năng ñịnh nghĩa chồng
các toán tử. Các toán tử sau khi ñược ñịnh nghĩa chồng cho lớp có thể sử dụng với
các ñối tượng của lớp ñó theo cách tương tự như với các biến thuộc kiểu dữ liệu
chuẩn.
Ví dụ:
class SP
{
double a, b;
public:
SP operator+(SP u2);
92
};
SP SP::operator+(SP u2)
{
SP u;
u.a= a+u2.a;
có thể ñịnh nghĩa chồng toán tử ‘-‘ ñể thực hiện phép cộng (hai ñối tượng), nhưng
ñiều ñó rõ ràng không có ích lợi gì mà dễ gây ra nhầm lẫn.
Các hàm toán tử có thể ñược ñịnh nghĩa như là hàm thành phần của lớp hoặc như
một hàm bạn:
93
+ Trong trường hợp hàm toán tử là hàm thành phần của lớp (phương thức): khi ñó
hàm ñã có một ñối (tham số) ngầm ñịnh (xác ñịnh chính ñối tượng ñang gọi hàm), do
vậy với toán tử một ngôi thì hàm toán tử không chứa ñối nào, còn với toán tử hai
ngôi thì hàm toán tử có một ñối.
+ Trong trường hợp hàm toán tử là hàm bạn: toán tử bao nhiêu ngôi thì hàm cần
có bấy nhiêu ñối.
Chú ý: Vì các toán tử phải thao tác trên các dữ liệu của ñối tượng mà các dữ liệu
thường là các thành phần riêng nên hàm toán tử không thể là một hàm tự do.
Vậy khi nào thì ñịnh nghĩa (hàm toán tử) là hàm thành phần, khi nào là hàm bạn?
Nguyên tắc chung là: nếu toán tử chỉ làm việc với các ñối tượng của cùng một lớp thì
ñịnh nghĩa là hàm thành phần hay hàm bạn ñều ñược, nhưng nếu toán tử làm việc với
các ñối tượng thuộc nhiều lớp khác nhau thì nó bắt buộc phải là hàm bạn.
Một số trường hợp cụ thể cần lưu ý:
+ Các toán tử = , [] phải ñược ñịnh nghĩa là hàm thành phần của lớp.
+ Các toán tử << , >> phải ñược ñịnh nghĩa là hàm bạn.
+ Các toán tử ++ , -- có thể ñược sử dụng theo hai cách khác nhau (tiền tố và hậu
tố), và ñiều này ñòi hỏi hai hàm toán tử khác nhau.
Trong thực tế thường hay ñịnh nghĩa các hàm toán tử là các phương thức của lớp,
vì thế chúng ta sẽ ñề cập chi tiết hơn trong
§
3. Cách ñịnh nghĩa chồng một số toán tử
quan trọng ñược trình bày trong
§
double b; // Phần ảo
public:
SP operator-();
} ;
SP SP:: operator-()
{
SP u ;
u.a = - this->a ;
u.b = - this->b ;
return u;
}
Cách dùng:
SP u, v;
u = -v;
Chú ý: Các phép toán ++ và -- có thể sử dụng theo hai cách khác nhau (tiền tố và
hậu tố) nên khi ñịnh nghĩa ñòi hỏi phải có hai cách khác nhau như sau:
+ Cho dạng tiền tố:
operator++()
operator--()
+ Cho dạng hậu tố sử dụng thêm ñối giả int:
operator++(int)
operator--(int)
3.3. Toán tử hai toán hạng
Với các phương thức toán tử hai toán hạng thì con trỏ this ứng với toán hạng thứ
nhất, nên trong phương thức chỉ cần dùng một ñối tường minh ñể biểu thị toán hạng
thứ hai. Ví dụ phương thức toán tử ‘+’ ñể cộng hai ñối tượng kiểu SP (số phức) có
thể viết như sau:
class SP
{
double a; // Phần thực