Tải bản đầy đủ (.pdf) (14 trang)

Định nghĩa chồng toán tử

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (230.68 KB, 14 trang )


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 ;


u.b = u1.b + u2.b ;
return u;
}
};
void main()
{
SP u, u1, u2;
u = cong(u1, u2); // u là tổng u1+u2
}
1.2. Xây dựng hàm toán tử cộng hai số phức
Trong ví dụ về lớp SP ở trên, chúng ta ñã xây dựng hàm cộng hai số phức bằng
cách sử dụng hàm bạn. Tuy vậy, trong trường hợp này, chúng ta có thể không cần sử
dụng hàm bạn vì chỉ làm việc với một lớp.

91

Ví dụ sau có cùng mục ñích (cộng hai số phức) nhưng xây dựng hàm cong là một
phương thức của lớp SP:
class SP
{
double a, b; // Phần thực, phần ảo
public:
SP cong(SP u2);
};
SP SP::cong(SP u2)
{
SP u;
u.a= a+u2.a;
u.b= b+u2.b;
return u;

}
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;

u.b= b+u2.b;
return u;
}
void main()
{
SP u, v, u1, u2, u3, u4;
u= u1+u2; // u là tổng u1+u2
v= u1+u2+u3+u4; // v là tổng u1+u2+u3+u4
}
Nhận xét:
Toán tử cộng ‘+’ ñóng vai trò như hàm cong ở ví dụ trên, và thực chất chương
trình dịch cũng hiểu nó như một hàm. Nói cách khác chỉ thị u= u1+u2 trong trường
hợp này ñược hiểu là u= u1.operator+(u2). Nhưng rõ ràng cách sử dụng toán tử làm
cho các biểu thức tự nhiên và ngắn gọn hơn nhiều.
§
2. GIỚI HẠN CỦA ðỊNH NGHĨA CHỒNG TOÁN TỬ
2.1. Các toán tử có thể ñịnh nghĩa chồng
Phần lớn các toán tử trong C
++
ñều có thể ñịnh nghĩa chồng, ngoại trừ các toán tử
truy nhập vào các thành phần ‘.’, toán tử xác ñịnh phạm vi ‘::’, toán tử ñiều kiện ‘?:’
và toán tử sizeof.
Chú ý rằng ngay trong cụm từ “ñịnh nghĩa chồng” ñã phản ánh rõ: không thể tạo
ra các toán tử mới mà chỉ ñịnh nghĩa lại các toán tử ñã có ñể có thể làm việc với
những kiểu dữ liệu khác với thiết kế chuẩn của nó.
2.2. Các nguyên tắc khi ñịnh nghĩa chồng toán tử
Các toán tử ñịnh nghĩa chồng phải bảo toàn số ngôi của chính toán tử ñó (theo
cách hiểu thông thường), ví dụ có thể ñịnh nghĩa toán tử ‘-‘ một ngôi (ñảo dấu) và hai
ngôi nhưng không thể ñịnh nghĩa toán tử gán ‘=’ là một ngôi.
Các toán tử ñịnh nghĩa chồng nên bảo toàn ý nghĩa nguyên thủy của nó, ví dụ ta

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
§

4.

§
3. PHƯƠNG THỨC TOÁN TỬ
3.1. Cách xây dựng phương thức toán tử
Các phương thức toán tử ñược xây dựng như các phương thức thông thường, chỉ
có khác cách ñặt tên. Tên của phương thức toán tử (cũng giống như hàm toán tử)
ñược tạo bằng cách ghép từ khoá operator với một phép toán (toán tử). Chúng ta chỉ
có thể sử dụng các phép toán ñã ñược ñịnh nghĩa trong C
++
ñể ñịnh nghĩa phương
thức cho một lớp mới, nên còn ñược gọi là ñịnh nghĩa chồng toán tử (operator
overloading).
Ví dụ:
operator+
operator<<
operator>>
Cũng giống như phương thức thông thường, phương thức toán tử có ñối ñầu tiên
(ñối không tường minh) là con trỏ this.
3.2. Toán tử một toán hạng
Các phương thức toán tử một toán hạng (một ngôi) dùng ngay con trỏ this ñể biểu
thị toán hạng duy nhất này, nên trong phương thức sẽ không có ñối tường minh. Ví
dụ phương thức toán tử ‘-‘ ñể ñổi dấu một ñối tượng kiểu SP (số phức) có thể viết
như sau:

94

class SP
{
double a; // Phần thực

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

double b; // Phần ảo
public:
SP operator+(SP u2);
} ;

×