operator overloading
play

Operator Overloading Do not change semantics Overload related sets - PowerPoint PPT Presentation

Contents Basics Consider all usages of the overloaded operator Complex number example Operator Overloading Do not change semantics Overload related sets of operators Time example Prefix ++ and postfix ++ operator[]


  1. Contents  Basics  Consider all usages of the overloaded operator  Complex number example Operator Overloading  Do not change semantics  Overload related sets of operators  Time example  Prefix ++ and postfix ++  operator[] C++ Object Oriented Programming  Assignment operator: operator= Pei-yih Ting  Function call operator: operator() NTOU CS  Smart pointers  Memory allocation operators: operator new/delete  Type conversion operators  Unary operator+ 24-1 24-2 Basic Overloading Operator Overloading  Operator overloading in ANSI C  There are two possibilities for the following int x, y, z; MyClass obj1, obj2; double q, r, t; The same operator can do different things. obj1 + obj2; z = x + y; q = r + t; Compiler would translate the above into one of the  Overloading in C++ following function call if one of them is defined: Array(); Overloaded constructors  First: calling member function Array(int arraySize); MyClass MyClass::operator+(MyClass rhs) void quit() { i.e. obj1.operator+(obj2) cout << "So you want to save before quitting?\n";  Second: calling global function } void quit(char *customMessage) { MyClass operator+(MyClass lhs, MyClass rhs) cout << customMessage << endl; i.e. operator+(obj1, obj2) } (If both of them are defined, the global one will be invoked. Functions with the same name can do different jobs. Do not take this as a practicing rule!!) 24-3 24-4

  2. Operator Overloading (cont’d) First Solution with Overloading  Consider the following MenuItem class which describes the item on  Add a member function which overloads operator+() a restaurant menu class MenuItem { class MenuItem { public: public: MenuItem(int itemPrice, char *itemName); MenuItem(int itemPrice, char *itemName); MenuItem(const MenuItem &src); MenuItem(const MenuItem &src); ~MenuItem(); ~MenuItem(); void display() const; void display() const; int operator+(const MenuItem &secondItem) const; private: private: int m_price; int m_price; char *m_name; or MenuItem secondItem char *m_name; }; };  We would like to do the following  The function is defined as follows void main() { int MenuItem::operator+(const MenuItem &secondItem) const MenuItem item1(250, "Chicken Florentine"); { MenuItem item2(120, "Tiramisu"); return m_price + secondItem.m_price; cout << "You ordered the following items:"; } item1.display(); item2.display(); cout << "The total is $" << item1 + item2 << ".\n"; Left operand of + Right operand of + } 24-5 24-6 Behavior of Overloaded Operator Behavior (cont’d)  Add a third menu item  The following statement still fails MenuItem item1(250, "Chicken Florentine"); item1 + (item2 + item3) MenuItem item2(120, "Tiramisu"); error C2678: binary '+' : no operator defined which takes a left-hand MenuItem item3(50, "Mineral Water"); int total; operand of type 'class MenuItem' (or there is no acceptable conversion) total = item1 + item2 + item3; Why? error C2677: binary '+' : no global operator defined which takes type  This is equivalent to Menuitem (item1) + int 'class MenuItem' (or there is no acceptable conversion) Why?  Solution: add another overloaded operator function  item1 + item2 returns an int int MenuItem::operator+(int currentTotal) {  you then have int + Menuitem (item3) return currentTotal + m_price; The overloaded member function can only be called by an instance of the class. }  Solution: make the overloaded function toplevel Why does this function not have to be toplevel (i.e. global)? int operator+(int currentTotal, MenuItem &secondItem)  Conclusion { make this function When you overload an operator, you are responsible for the correct behavior of return currentTotal + secondItem.m_price; a friend of MenuItem } the operator in all possible circumstances. could be reference or value 24-7 24-8

  3. Alternative Solution Complex Number Example  Use conversion constructor together with global operator+(const  Complex class represents a complex number (real, imaginary), MenuItem &, const MenuItem &) define two mathematic operations (no side effect) class MenuItem { Complex Complex::add(const Complex &secondNumber) const { friend int operator+(const MenuItem &firstItem, Complex tmp(m_real+secondNumber.m_real, const MenuItem &secondItem); public: m_imaginary+secondNumber.m_imaginary); MenuItem(int itemPrice, char *itemName); return tmp; MenuItem(int price); } MenuItem(const MenuItem &src); Complex Complex::multiply(const Complex &secondNumber) const { ~MenuItem(); Complex tmp(m_real*secondNumber.m_real- void display() const; m_imaginary*secondNumber.m_imaginary, private: m_real*secondNumber.m_imaginary+ int m_price; m_imaginary*secondNumber.m_real); char *m_name; return tmp; }; }  The conversion constructor  main() c + z * z MenuItem::MenuItem(int price): m_price(price), m_name(0) { Complex c(0.1, 0), z(0, 0); } for (int i=1; i<MaxIterations; i++) {  Overload the operator at the toplevel with two MenuItem objects z = c.add(z.multiply(z)); int operator+(const MenuItem &firstItem, const MenuItem &secondItem) { if (fabs(z.getRealPart())>2.0 || fabs(z.getImaginaryPart())>2.0) break; return firstItem.m_price + secondItem.m_price; } } 24-9 24-10 Complex Number (cont'd) Dubious Operator Overloading  Here are some actual examples from a textbook  Let us overload + and * Can you guess what these operators mean? Complex Complex::operator+(const Complex &secondNumber) const { Complex tmp(m_real+secondNumber.m_real, Stack s; … m_imaginary+secondNumber.m_imaginary); This is too far away!! s+5; return tmp; x = s--; } Complex Complex::operator*(const Complex &secondNumber) const { They are used to stand for the following Complex tmp(m_real*secondNumber.m_real- s.push(5); m_imaginary*secondNumber.m_imaginary, x = s.pop(); m_real*secondNumber.m_imaginary+ m_imaginary*secondNumber.m_real);  Overloading obscure operators can be dangerous return tmp; Redefine ^ (bitwise XOR) to mean "power" } It won't work as expected, ex.  main() Integer x; x ^ 2 + 1 // if x is 5, you want to get 26, but you get 125 instead Complex c(0.1, 0), z(0, 0); Reason: ^ has lower precedence than + for (int i=1; i<MaxIterations; i++) { z = c + z * z;  Illegal overloading if (fabs(z.getRealPart())>2.0 || fabs(z.getImaginaryPart())>2.0) break; int operator+(int number1, int number2) { } return number1-number2; error C2803: 'operator +' must have at least  Related operators +=, *= } one formal parameter of class type 24-11 24-12

Recommend


More recommend