Liên Mạng VietNam || GiaiTri.com | GiaiTriLove.com | GiaiTriChat.com | LoiNhac.com | Đăng Nhập | Gia Nhập |
là hoàn toàn hợp lệ vì các biến ở đây đều có kiểu là các kiểu dữ liệu cơ bản. Tuy nhiên, việc chúng ta có thể thực hiện thao tác sau đây có vẻ không hiển nhiên lắm (thực tế là nó không hợp lệ):
int a, b, c;
a = b + c;
Phép gán một lớp (hay một cấu trúc) với một đối tượng cùng kiểu là được phép (copy constructor mặc định). Nhưng phép cộng sẽ gây ra lỗi vì nó được dùng với các kiểu dữ liệu không cơ bản.struct { char product [50]; float price; } a, b, c;
a = b + c;
Để làm quá tải một toán tử chúng ta chỉ cần viết một hàm thành viên của lớp có tên operator theo sau là toán tử chúng ta muốn làm quá tải. Mẫu như sau:+ - * / = < > += -= *= /= << >>
<<= >>= == != <= >= ++ -- % & ^ ! |
~ &= ^= |= && || %= [] () new delete
Dưới đây là ví dụ về việc quá tải toán tử +. Chúng ta chuẩn bị tính tổng hai vector hai chiều a(3,1) và b(1,2). Phép cộng giữa hai vector hai chiều chỉ đơn giản là cộng hai toạ độ x để lấy toạ độ kết quả x , cộng hai toạ độ y để lấy toạ độ kết quả y. Trong trường hợp này kết quả sẽ là (3+1,1+2) = (4,3).
type operator sign (parameters);
#include <iostream.h> class CVector { public: int x,y; CVector () {}; CVector (int,int); CVector operator + (CVector); }; CVector::CVector (int a, int b) { x = a; y = b; } CVector CVector::operator+ (CVector param) { CVector temp; temp.x = x + param.x; temp.y = y + param.y; return (temp); } int main () { CVector a (3,1); CVector b (1,2); CVector c; c = a + b; cout << c.x << "," << c.y; return 0; } | 4,3 |
Hàm operator+ của lớp CVector được dùng để quá tải toán tử số học +. Hàm này có thể được gọi bằng một trong các cách:CVector (int, int); // Hàm có tên Vector (constructor)
CVector operator+ (CVector);// Hàm operator+ trả về kiểu CVector
c = a + b;
c = a.operator+ (b);
Hãy chú ý rằng chúng ta đã thêm vào constructor rỗng (không có tham số) và chúng ta định nghĩa nó với một khối lệnh cũng rỗng nốt: CVector () { }; điều này là cần thiết vì còn có một constructor khác, CVector (int, int);và vì vậy các constructors mặc định không tồn tại trong CVector nếu chúng ta không khai nó một cách rõ ràng. Khai báo sau đây sẽ là không hợp lệ:
Dù thế nào chăng nữa, tôi cần phải cảnh báo rằng một khối lệnh rỗng không nên để tạo một constructor vì nó không thoả mãn chức năng tối thiểu mà một constructor nên có, đó là việc khởi tạo tất cả các biến trong lớp. Trong trường hợp của chúng ta constructor này đã để các biến x và y là không xác định. Vì vậy một khai báo thích hợp hơn sẽ là một cái gì đó giống như thế này: để cho đơn giản tôi đã không viết vào trong ví dụ trên. |
Như bạn có thể thấy trong bảng này, có hai cách để quá tải các toán tử của lớp: như là một hàm thành viên và như là một hàm toàn cục. Khác nhau giữa chúng không rõ ràng tuy nhiên tôi cần phải nhắc lại rằng các hàm không phải là thành viên của một lớp không thể truy xuất đến các thành viên là private hoặc protected của lớp trừ phi hàm toàn cục đó là bạn của lớp (thuật ngữ này sẽ được đề cập đến ở bài sau).* trong đó a là một đối tượng của lớp A, b là một đối tượng của lớp B và c là một đối tượng của lớp C.
Biểu thức Toán tử (@) Hàm thành viên Hàm toàn cục @a + - * & ! ~ ++ -- A::operator@() operator@(A) a@ ++ -- A::operator@(int) operator@(A, int) a@b + - * / % ^ & | < > == != <= >= << >> && || , A::operator@(B) operator@(A, B) a@b = += -= *= /= %= ^= &= |= <<= >>= [ ] A::operator@(B) - a(b, c...) () A::operator()(B, C...) - a->b -> A::operator->() -
#include <iostream.h> class CDummy { public: int isitme (CDummy& param); }; int CDummy::isitme (CDummy& param) { if (¶m == this) return 1; else return 0; } int main () { CDummy a; CDummy* b = &a; if ( b->isitme(a) ) cout << "yes, &a is b"; return 0; } | yes, &a is b |
Trong thực tế đây chính là đoạn mã được mặc định tạo ra nếu chúng ta không viết hàm thành viên operator=.CVector& CVector::operator= (const CVector& param)
{
x=param.x;
y=param.y;
return *this;
}
#include <iostream.h> class CDummy { public: static int n; CDummy () { n++; }; ~CDummy () { n--; }; }; int CDummy::n=0; int main () { CDummy a; CDummy b[5]; CDummy * c = new CDummy; cout << a.n << endl; delete c; cout << CDummy::n << endl; return 0; } | 7 6 |
Hai lời gọi trong ví dụ trên đều tham chiếu đến cùng một biến: biến tĩnh n trong lớp CDummy.
cout << a.n;
cout << CDummy::n;