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
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:
- bai_giang_lap_trinh_huong_doi_tuong_tap_1_chuong_5_qua_tai_t.pdf