Bài giảng Lập trình hướng đối tượng - Chương 5: Quá tải toán tử

• Quá tải toán tử đối với lớp

• Quá tải toán tử nhị nguyên

• Quá tải toán tử quan hệ & luận lý

• Quá tải toán tử đơn nguyên

• Hàm toán tử friend

• Toán tử gán

 

pdf28 trang | Chuyên mục: C/C++ | Chia sẻ: tuando | Lượt xem: 410 | 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 5: Quá tải toán tử, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
lt;< ", Y: " << y << "\n"; 
 return 0; 
} 
Chương 5 Quá tải toán tử 
151 
151 
@ Toán hạng bên trái được truyền cho tham số thứ nhất, toán hạng bên phải được 
truyền cho tham số thứ hai. 
• Quá tải một toán tử bằng cách dùng một friend cung cấp đặc điểm quan trọng 
mà một hàm thành viên không thể có được. Với hàm toán tử friend, có thể để 
cho những đối tượng được sử dụng trong các phép toán có các kiểu định sẵn, ở 
đó kiểu định sẵn nằm ở bên trái toán tử. 
Trong ví dụ 2.3, chương 5, hàm toán tử thành viên được quá tải 
coord coord::operator+(int i) 
câu lệnh ob1 = ob2 + 100; là đúng 
còn câu lệnh ob1 = 100 + ob2; là sai 
Với hàm toán tử friend, có thể định nghiã hàm quá tải sao cho toán hạng bên 
trái là một đối tượng và toán hạng bên phải là kiểu định sẵn. Sau đó, quá tải 
toán tử này lần nữa với toán hạng bên trái là kiểu định sẵn và toán hạng bên 
phải là một đối tượng. 
Ví dụ 5.2 
// Use friend operator functions to add flexibility. 
#include 
class coord { 
 int x, y; // coordinate values 
public: 
 coord() { x=0; y=0; } 
 coord(int i, int j) { x=i; y=j; } 
 void get_xy(int &i, int &j) { i=x; j=y; } 
 friend coord operator+(coord ob1, int i); 
 friend coord operator+(int i, coord ob1); 
}; 
Chương 5 Quá tải toán tử 
152 
152
// Overload for ob + int. 
coord operator+(coord ob1, int i) 
{ 
 coord temp; 
 temp.x = ob1.x + i; 
 temp.y = ob1.y + i; 
 return temp; 
} 
// Overload for int + ob. 
coord operator+(int i, coord ob1) 
{ 
 coord temp; 
 temp.x = ob1.x + i; 
 temp.y = ob1.y + i; 
 return temp; 
} 
int main() 
{ 
 coord o1(10, 10); 
 int x, y; 
 o1 = o1 + 10; // object + integer 
 o1.get_xy(x, y); 
 cout << "(o1+10) X: " << x << ", Y: " << y << "\n"; 
 o1 = 99 + o1; // integer + object 
 o1.get_xy(x, y); 
 cout << "(99+o1) X: " << x << ", Y: " << y << "\n"; 
 return 0; 
} 
Chương 5 Quá tải toán tử 
153 
153 
@ Do đó hai câu lệnh này lúc này hoàn toàn đúng 
ob1 = ob2 + 100; 
ob1 = 100 + ob2; 
• Bằng cách truyền toán hạng cho friend như một tham số tham chiếu, những 
thay đổi xảy ra bên trong hàm friend có ảnh hưởng đến đối tượng tạo ra lời gọi. 
Quá tải toán tử "++" bằng cách dùng hàm friend. 
Ví dụ 5.3 
// Overload the ++ using a friend. 
#include 
class coord { 
 int x, y; // coordinate values 
public: 
 coord() { x=0; y=0; } 
 coord(int i, int j) { x=i; y=j; } 
 void get_xy(int &i, int &j) { i=x; j=y; } 
 friend coord operator++(coord &ob); 
}; 
// Overload ++ using a friend. 
coord operator++(coord &ob) // use reference parameter 
{ 
 ob.x++; 
 ob.y++; 
 return ob; // return object generating the call 
} 
int main() 
{ 
 coord o1(10, 10); 
 int x, y; 
 ++o1 ; // o1 is passed by reference 
Chương 5 Quá tải toán tử 
154 
154
 o1.get_xy(x, y); 
 cout << "(++o1) X: " << x << ", Y: " << y << "\n"; 
 return 0; 
} 
@ Nếu dùng trình biên dịch mới (theo chuẩn ANSI C++), có thể phân biệt giữa các 
dạng đứng trước và đứng sau của các toán tử tăng hay giảm khi dùng hàm toán tử 
friend. Chỉ cần bổ sung tham số nguyên notused khi định nghiã dạng đứng sau 
(nghiã là toán tử "++" đứng sau toán hạng) . 
coord operator++(coord &ob); // prefix ++O 
coord operator++(coord &ob, int notused); // postfix O++ 
Bài tập V 
1. Hãy quá tải toán tử "-" và "/" đối với lớp coord dùng hàm friend. Viết chương 
trình. 
2. Quá tải lớp coord để sử dụng các đối tượng coord trong các phép toán mà một giá 
trị nguyên được nhân với mỗi toạ độ, cho phép các phép toán dùng thứ tự của nó : 
 ob * int hoặc int * ob 
3. Sử dụng friend, hãy quá tải toán tử "--" đối với lớp coord. Viết chương trình cho cả 
hai dạng đứng trước và sau. 
Chương 5 Quá tải toán tử 
155 
155 
VI/ Toán tử gán 
Theo mặc định, khi một toán tử gán được áp dụng cho một đối tượng thì một bản sao 
từng bit được đặt vào trong đối tượng bên trái. 
Tuy nhiên, có những trường hợp mà bản sao từng bit chính xác là không cần. Xem 
một số ví dụ trong chương 2, những trường hợp khi một đối tượng sử dụng bộ nhớ. 
Trong những trường hợp này, cần phải có một phép gán đặc biệt. 
• Quá tải toán tử "=" trong lớp strtype 
Ví dụ 6.1 
#include 
#include 
#include 
class strtype { 
 char *p; 
 int len; 
public: 
 strtype(char *s); 
 ~strtype() { 
 cout << "Freeing " << (unsigned) p << '\n'; 
 delete [] p; 
 } 
 char *get() { return p; } 
 strtype &operator=(strtype &ob); 
}; 
strtype::strtype(char *s) 
{ 
 int l; 
 l = strlen(s)+1; 
 p = new char [l]; 
 if(!p) { 
 cout << "Allocation error\n"; 
 exit(1); 
Chương 5 Quá tải toán tử 
156 
156
 } 
 len = l; 
 strcpy(p, s); 
} 
// Assign an object. 
strtype &strtype::operator=(strtype &ob) 
{ 
 // see if more memory is needed 
 if(len < ob.len) { // need to allocate more memory 
 delete [] p; 
 p = new char [ob.len]; 
 if(!p) { 
 cout << "Allocation error\n"; 
 exit(1); 
 } 
 } 
 len = ob.len; 
 strcpy(p, ob.p); 
 return *this; 
} 
int main() 
{ 
 strtype a("Hello"), b("There"); 
 cout << a.get() << '\n'; 
 cout << b.get() << '\n'; 
 a = b; // now p is not overwritten 
 cout << a.get() << '\n'; 
 cout << b.get() << '\n'; 
 return 0; 
} 
Chương 5 Quá tải toán tử 
157 
157 
@ Có hai đặc điểm với hàm operator=() trong ví dụ này 
 + nó có một tham số tham chiếu 
 + nó trả về tham chiếu chứ không phải một đối tượng 
Bài tập VI 
1. Cho khai báo lớp dưới đây, hãy thêm vào các chi tiết để tạo nên một kiểu mảng 
"an toàn". Sau đó, hãy quá tải toán tử gán để cho bộ nhớ được cấp phát của mảng 
không bị hủy tình cờ. 
class dynarray { 
 int *p; 
 int size; 
public: 
 dynarray(int s); // pass size of array in s 
 int &put(int i); // return reference to element i 
 int get(int i); // return value of element i 
 // create operator=() function 
 ... 
}; 
Chương 5 Quá tải toán tử 
158 
158
Bài tập chương 5 
1. Quá tải các toán tử >> và << đối với lớp coord để cho có các kiểu phép toán sau 
đây : 
ob << integer ; 
ob >> integer ; 
Viết chương trình làm cho các toán tử trên nâng các giá trị x và y lên một đại lượng 
được chiû rõ. 
2. Cho lớp 
class three_d { 
 int x, y, z; 
public: 
 three_d(int i, int j, int k) 
 { 
 x = i; y = j; z = k; 
 } 
 three_d() { x=0; y=0; z=0; } 
 void get(int &i, int &j, int &k) 
 { 
 i = x; j = y; k = z; 
 } 
}; 
Hãy quá tải các toán tử +, -, ++ và -- đối với lớp này. Đối với các toán tử tăng và 
giảm chiû quá tải theo dạng đứng trước. Viết chương trình thực hiện các yêu cầu sau : 
- khai báo các đối tượng : three_d o1(6,8,10), o2(3,4,5), o3; 
- thực hiện các phép toán : o3 = o1 + o2; 
 o3 = o1 - o2; 
 ++o1 ; 
 --o1; 
- xuất nội dung x, y, z của các đối tượng trên. 
3. Thực hiện lại bài tập 2 dưới dạng tham số tham chiếu đối với các hàm toán tử. 
Dùng hàm friend đối với các toán tử tăng và giảm. 
Chương 5 Quá tải toán tử 
159 
159 
4. Viết chương trình thực hiện quá tải toán tử + đối với lớp three_d để cho nó nhận 
các kiểu phép toán sau : ob + double; double + ob; 
5. Viết chương trình thực hiện quá tải các toán tử ==, !=, và // đối với lớp three_d. 
6. Viết chương trình tạo lớp strtype để cho phép các kiểu toán tử sau : 
 * ghép chuổi bằng cách dùng toán tử + 
 * gán chuổi bằng cách dùng toán tử = 
 * so sánh chuổi bằng cách dùng các toán tử > , < và == 
có thể dùng chuổi có độ dài cố định. Trong đó : 
- một biến chuổi s[80] có dạng private 
- hàm tạo không đối số, thực hiện việc khởi tạo chuổi s là NULL 
- hàm tạo có một đối số *p, thực hiện việc chép nội dung chuổi p cho s 
- hàm char *get() trả về giá trị của chuổi s 
7. Hãy bổ sung các hàm toán tử cần thiết vào chương trình sau. 
* Toán tử quá tải + cộng mỗi phần tử của toán hạng. 
* Toán tử quá tải - trừ phần tử toán hạng bên trái với mỗi phần tử của toán hạng bên 
phải. 
* Toán tử quá tải == trả về giá trị đúng nếu mỗi phần tử của mỗi toán hạng là giống 
nhau và trả về giá trị sai nếu ngược lại. 
#include 
class array { 
 int nums[10]; 
public: 
 array(); 
 void set(int n[10]); 
 void show(); 
 array operator+(array ob2); 
 array operator-(array ob2); 
 int operator==(array ob2); 
}; 
Chương 5 Quá tải toán tử 
160 
160
array::array() 
{ 
 int i; 
 for(i=0; i<10; i++) nums[i] = 0; 
} 
void array::set(int *n) 
{ 
 int i; 
 for(i=0; i<10; i++) nums[i] = n[i]; 
} 
void array::show() 
{ 
 int i; 
 for(i=0; i<10; i++) 
 cout << nums[i] << ' '; 
 cout << "\n"; 
} 
// Fill in operator functions. 
// ... 
int main() 
{ 
 array o1, o2, o3; 
 int i[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
 o1.set(i); 
 o2.set(i); 
Chương 5 Quá tải toán tử 
161 
161 
 o3 = o1 + o2; 
 o3.show(); 
 o3 = o1 - o3; 
 o3.show(); 
 if(o1==o2) cout << "o1 equals o2\n"; 
 else cout << "o1 does not equal o2\n"; 
 if(o1==o3) cout << "o1 equals o3\n"; 
 else cout << "o1 does not equal o3\n"; 
 return 0; 
} 
8. Thực hiện lại bài tập 7 với quá tải các toán tử bằng cách dùng hàm friend. 
Chương 5 Quá tải toán tử 
162 
162

File đính kèm:

  • pdfbai_giang_lap_trinh_huong_doi_tuong_tap_1_chuong_5_qua_tai_t.pdf