Chapter 8 - Operator Overloading

Chia sẻ: Đặng Quang Hưng | Ngày: | Loại File: PDF | Số trang:80

0
152
lượt xem
46
download

Chapter 8 - Operator Overloading

Mô tả tài liệu
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Sử dụng các toán tử với các đối tượng (operator overloading) – đối với một số lớp, sử dụng toán tử trong sáng hơn sử dụng các lời gọi hàm object2 = object1.add(object2); object2 = object2 + object1;

Chủ đề:
Lưu

Nội dung Text: Chapter 8 - Operator Overloading

  1. 1 Chapter 8 - Operator Overloading Outline 8.1 Introduction 8.2 Fundamentals of Operator Overloading 8.3 Restrictions on Operator Overloading 8.4 Operator Functions as Class Members vs. as friend Functions 8.5 Overloading Stream-Insertion and Stream-Extraction Operators 8.6 Overloading Unary Operators 8.7 Overloading Binary Operators 8.8 Case Study: Array Class 8.9 Converting between Types 8.10 Case Study: A String Class 8.11 Overloading ++ and -- 8.12 Case Study: A Date Class 8.13 Standard Library Classes string and vector © 2003 Prentice Hall, Inc. All rights reserved.
  2. 2 8.1 Introduction • Sử dụng các toán tử với các đối tượng (operator overloading) – đối với một số lớp, sử dụng toán tử trong sáng hơn sử dụng các lời gọi hàm object2 = object1.add(object2); object2 = object2 + object1; – toán tử cảm ngữ cảnh (sensitive to context) Ví dụ •
  3. 3 8.2 Fundamentals of Operator Overloading • Các kiểu dữ liệu – Có sẵn (Built in) (int, char) hoặc kiểu người dùng (user- defined) – Có thể sử dụng các toán tử có sẵn cho các kiểu dữ liệu người dùng • Không thể tạo toán tử mới • Overloading operators – Tạo một hàm của lớp – Đặt tên hàm là operator tiếp theo là ký hiệu • Operator+ dành cho phép cộng + © 2003 Prentice Hall, Inc. All rights reserved.
  4. 4 8.2 Fundamentals of Operator Overloading • Sử dụng toán tử với một đối tượng – Nó phải được overloaded cho lớp đó • ngoại trừ: • phép gán, = – phép gán từng thành viên của đối tượng này cho đối tượng kia (Memberwise assignment between objects) • toán tử địa chỉ, & – trả về địa chỉ của đối tượng • cả hai đều có thể được overloaded • Overloading cho ký hiệu ngắn gọn object2 = object1.add(object2); object2 = object2 + object1; © 2003 Prentice Hall, Inc. All rights reserved.
  5. 5 8.3 Restrictions on Operator Overloading • Không thể thay đổi: – Hoạt động của các toán tử đối với các kiểu dữ liệu có sẵn • ví dụ., không thể thay đổi phép cộng số nguyên – Thứ tự ưu tiên của các toán tử – Quan hệ kết hợp - Associativity (left-to-right hoặc right-to- left) – Số lượng toán hạng (operand) • & là toán tử đơn, chỉ dành cho một toán hạng • Không thể tạo các toán tử mới • Các toán tử phải được overloaded một cách tường minh – Overload + không có nghĩa cả += cũng được overload © 2003 Prentice Hall, Inc. All rights reserved.
  6. 6 8.3 Restrictions on Operator Overloading Operators that can be overloaded + - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= > >>= [] () new delete new[] delete[] Operators that cannot be overloaded . .* :: ?: sizeof © 2003 Prentice Hall, Inc. All rights reserved.
  7. 7 8.4 Operator Functions As Class Members Vs. As Friend Functions • aa@bb aa.operator@(bb) hoặc operator@(aa,bb) • @aa aa.operator@( ) hoặc operator@(aa) • aa@ aa.operator@(int) hoặc operator@(aa,int) • Operator functions – Member functions • Sử dụng từ khóa this để ngầm lấy tham số – là toán hạng bên trái đối với các toán tử hai ngôi (ví dụ +) – là toán hạng duy nhất đối với các toán tử một ngôi • Toán tử và toán hạng bên trái nhất phải thuộc cùng lớp – Non member functions • Cần tham số cho cả hai toán hạng • Có thể lấy các đối tượng không thuộc lớp của toán tử • Phải là friend để truy nhập các dữ liệu private hoặc protected © 2003 Prentice Hall, Inc. All rights reserved.
  8. 8 8.4 Operator Functions As Class Members Vs. As Friend Functions • Các phép toán có tính giao hoán – phép + cần có tính giao hoán • cả “a + b” và “b + a” đều phải chạy được – giả sử ta có hai lớp khác nhau – Overloaded operator chỉ có thể là member function khi lớp của nó ở bên trái • HugeIntClass + long int – trường hợp kia, cần một non-member overload function • long int + HugeIntClass © 2003 Prentice Hall, Inc. All rights reserved.
  9. 9 8.5 Overloading Stream-Insertion and Stream-Extraction Operators • > – đã được overloaded để xử lý từng kiểu built-in – cũng có thể overload để xử lý kiểu dữ liệu người dùng • Overloaded cần toán tử trái kiểu istream & – Vậy, cả hai phải là non-member function • Chương trình ví dụ – Class PhoneNumber • Lưu trữ một số điện thoại – In số điện thoại đã được định dạng tự động • (123) 456-7890 © 2003 Prentice Hall, Inc. All rights reserved.
  10. function prototype cho các hàm overload các toán 10 1 // Fig. 8.3: fig08_03.cpp tử >> và object 18 friend ostream &operator( istream&, PhoneNumber & ); 20 Biểu thức: cout
  11. 11 Outline ignore() bỏ qua một số ký tự input, số lượng được chỉ ra tại fig08_03.cpp tham số (mặc định là 1). (2 of 3) 40 // overloaded stream-extraction operator; cannot be 41 // a member function if we would like to invoke it with 42 // cin >> somePhoneNumber; 43 istream &operator>>( istream &input, PhoneNumber &num ) 44 { 45 input.ignore(); // skip ( 46 input >> setw( 4 ) >> num.areaCode; // input area code 47 input.ignore( 2 ); // skip ) and space 48 input >> setw( 4 ) >> num.exchange; // input exchange 49 input.ignore(); // skip dash (-) 50 input >> setw( 5 ) >> num.line; // input line Stream manipulator setw 51 giới hạn số ký tự được đọc. setw(4) cho phép đọc 3 ký 52 return input; // enables cin >> a >> b >> c; tự, dành chỗ cho ký tự null. © 2003 Prentice Hall, Inc. All rights reserved.
  12. 12 53 Outline 54 } // end function operator>> 55 56 int main() fig08_03.cpp 57 { (3 of 3) 58 PhoneNumber phone; // create object phone 59 fig08_03.cpp 60 cout > phone invokes operator>> by implicitly issuing 63 // the non-member function call operator>>( cin, phone ) 64 cin >> phone; 65 66 cout
  13. 13 8.6 Overloading Unary Operators • Overloading unary operators – Non-static member function, không cần tham số – Non-member function, một tham số • tham số phải là đối tượng hoặc tham chiếu đến đối tượng – Ghi nhớ, static function chỉ truy nhập static data • Ví dụ (8.10) – Overload ! để kiểm tra xâu ký tự có rỗng hay không – nếu là non-static member function, không cần tham số • !s trở thành s.operator!() class String { public: bool operator!() const; ... }; – nếu là non-member function, cần một tham số • s! trở thành operator!(s) class String { friend bool operator!( const String & ) ... } © 2003 Prentice Hall, Inc. All rights reserved.
  14. 14 8.7 Overloading Binary Operators • non-static member function, một tham số class String { public: const String &operator+=( const String & ); ... }; – y += z tương đương với y.operator+=( z ) • non-member function, hai tham số – tham số phải là đối tượng hoặc tham chiếu đến đối tượng class String { friend const String &operator+=( String &, const String & ); ... }; – y += z tương đương với operator+=( y, z ) © 2003 Prentice Hall, Inc. All rights reserved.
  15. 15 8.8 Case Study: Array class • Arrays in C++ – Không có kiểm tra khoảng – No range checking – Không thể so sánh == một cách có nghĩa – Không có phép gán mảng (tên mảng là const pointer) – không thể nhập/in cả mảng một lúc • mỗi lần một phần tử • Ví dụ: Cài đặt một lớp Array với – Range checking – Array assignment – mảng biết kích thước của mình – Output/input toàn bộ mảng bằng > – So sánh mảng với == và != © 2003 Prentice Hall, Inc. All rights reserved.
  16. 16 8.8 Case Study: Array class • Copy constructor – được dùng mỗi khi cần sao chép đối tượng • truyền bằng trị (trả về giá trị hoặc tham số) • khởi tạo một đối tượng bằng một bản sao của một đối tượng khác – Array newArray( oldArray ); – newArray là bản sao của oldArray – Prototype • Array( const Array & ); • Phải lấy tham biến – nếu không, tham số được truyền bằng giá trị – trình biên dịch sẽ cố tạo một bản sao bằng cách gọi copy constructor… – lặp vô tận © 2003 Prentice Hall, Inc. All rights reserved.
  17. 17 1 // Fig. 8.4: array1.h Outline 2 // Array class for storing arrays of integers. 3 #ifndef ARRAY1_H 4 #define ARRAY1_H array1.h (1 of 2) 5 6 #include 7 8 using std::ostream; 9 using std::istream; Prototype for copy constructor. 10 11 class Array { 12 friend ostream &operator( istream &, Array & ); 14 15 public: 16 Array( int = 10 ); // default constructor Hầu hết các toán tử được 17 Array( const Array & ); // copy constructor overloaded bằng member 18 ~Array(); // destructor function (trừ > phải 19 int getSize() const; // return size dùng non-member function). 20 21 // assignment operator 22 const Array &operator=( const Array & ); 23 24 // equality operator 25 bool operator==( const Array & ) const; © 2003 Prentice Hall, Inc. 26 All rights reserved.
  18. 18 Outline 27 // inequality operator; returns opposite of == operator array1.h (2 of 2) 28 bool operator!=( const Array &right ) const 29 { 30 return ! ( *this == right ); // invokes Array::operator== 31 Toán tử != chỉ cần trả về đảo của toán tử == . 32 } // end function operator!= Vậy, chỉ cần định nghĩa toán tử == 33 34 // subscript operator for non-const objects returns lvalue 35 int &operator[]( int ); 36 37 // subscript operator for const objects returns rvalue 38 const int &operator[]( int ) const; 39 40 private: 41 int size; // array size 42 int *ptr; // pointer to first element of array 43 44 }; // end class Array 45 46 #endif © 2003 Prentice Hall, Inc. All rights reserved.
  19. 19 1 // Fig 8.5: array1.cpp Outline 2 // Member function definitions for class Array 3 #include 4 array1.cpp (1 of 7) 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 #include 10 11 using std::setw; 12 13 #include // C++ standard "new" operator 14 15 #include // exit function prototype 16 17 #include "array1.h" // Array class definition 18 19 // default constructor for class Array (default size 10) 20 Array::Array( int arraySize ) 21 { 22 // validate arraySize 23 size = ( arraySize > 0 ? arraySize : 10 ); 24 25 ptr = new int[ size ]; // create space for array © 2003 Prentice Hall, Inc. 26 All rights reserved.
  20. 20 27 for ( int i = 0; i < size; i++ ) Outline 28 ptr[ i ] = 0; // initialize array 29 30 } // end Array default constructor array1.cpp (2 of 7) 31 32 // copy constructor for class Array; 33 // must receive a reference to prevent infinite recursion 34 Array::Array( const Array &arrayToCopy ) Ta phải khai báo một mảng số nguyên mới để các 35 : size( arrayToCopy.size ) đối tượng không chỉ đến cùng một vùng bộ nhớ. 36 { 37 ptr = new int[ size ]; // create space for array 38 39 for ( int i = 0; i < size; i++ ) 40 ptr[ i ] = arrayToCopy.ptr[ i ]; // copy into object 41 42 } // end Array copy constructor 43 44 // destructor for class Array 45 Array::~Array() 46 { 47 delete [] ptr; // reclaim array space 48 49 } // end destructor 50 © 2003 Prentice Hall, Inc. All rights reserved.
Đồng bộ tài khoản