Presentation is loading. Please wait.

Presentation is loading. Please wait.

Operator overloading. Operatorsand precedence zLeft to right associative y:: scope resolution y. direct member access y-> indirect member access y[] subscripting.

Similar presentations


Presentation on theme: "Operator overloading. Operatorsand precedence zLeft to right associative y:: scope resolution y. direct member access y-> indirect member access y[] subscripting."— Presentation transcript:

1 Operator overloading

2 Operatorsand precedence zLeft to right associative y:: scope resolution y. direct member access y-> indirect member access y[] subscripting y() function call y() function-style cast y++ postfix increment y-- postfix decrement Level 17 Level 16

3 Operators zRight to left associative y++ prefix increment y-- prefix decrement y~ one’s complement y! not y- unary minus y+ unary plus y& address of y* de-reference ynew allocate a single instance ynew[] allocate array of instances ydelete delete single instance ydelete[] delete multiple instances y() C-style cast Level 15 Level 14

4 Operators zLeft to right associative y* multiplication y/ division y% modulus y+ addition y- subtraction y<< shift left y>> shift right y< less than y<= less than or equal to y> greater than y>= greater than or equal to Level 13 Level 12 Level 11 Level 10

5 Operators zLeft to right associative y== equal to y!= not equal y& bitwise and y^ bitwise exclusive or y| bitwise inclusive or y&& logical and y|| logical or y?: conditional expression Level 9 Level 4 Level 8 Level 7 Level 6 Level 5 Level 3

6 Operators zRight to left associative y= assignment y*= multiply and assign y/= divide and assign y%= modulus and assign y+= addition and assign y-= subtract and assign y<<= shift left and assign y>>= shift right and assign y&= bitwise AND and assign y|= bitwise OR and assign y^= exclusive OR and assign y, comma (left to right) Level 2 Level 1

7 Outline zOperator overloading ymotivation yexamples yrestrictions yunary and binary overloaded operators zFriends zType conversion operators

8 Rule of Big Three zIf a class has any of ycopy constructor ydestructor yassignment operator zIt needs all three zDestructor usually shows up first zException: when destructor only decrements number of instances

9 Function overloading zOperators are really functions zThey have arguments zThey return values zThe only difference is that their names take on a specific form: yoperator+ yoperator[] yetc.

10 Function overloading (con’t) zAn overloaded function is one which has the same name but several different forms. zFor example, we overloaded the constructor for the Date class ydefault Date d; yinitializing Date d(9,22,99); ycopy Date d1(d); yother Date d(“Sept.,22,1999);

11 Operator overloading zJust as there may be many versions of a function due to overloading, there may be many versions of operators. zExample: operator/ ya = 14.0 / 2; (one float and one int argument) ya = 14.0 / 2.0; (two float arguments) ya = 14 / 2; (two ints, INTEGER DIVISION) zMany operators are already overloaded for us to handle a variety of argument types.

12 Operator Overloading zThe operator “+” also has different semantics depending on the type of its “arguments” zExample int i, j; double d, e; i + j; /* add two int */ i + d; /* add an int and a double */

13 Operator overloading zWe want user-defined types to behave like built-in types class complex { /* … */ }; complex a(2,1), b(3,0); … cout << a + b << a*b << -b; cout << (a != b);

14 More examples of operator overloading Vector v1, v2; v2 = v1; // overloaded assignment cin >> v1 >> v2; // overloaded >> cout << v1[5] << v2++; // overloaded <<, [], ++ Vector v3; v3 += (v1 - v2); // overloaded +=, -

15 Advantages of operator overloading zUser-defined types behave like built-in types yfamiliar notation (infix notation for binary ops) zAlternative to operator overloading yPostfix notation for unary operators: v1.incr(1).add(v2).print(); yPrefix notation for binary operators (Lisp-like) equal(v1, plus(v2, v3)); yVerbose and inconsistent

16 Extended example zEmployee class and objects class Employee { private: int idNum; double salary; public: Employee(const int id, const double salary); double addTwo(const Employee& emp); double operator+(const Employee& emp); double getSalary() { return salary; } }

17 The member functions ‘addTwo’ and operator+ double Employee::addTwo(const Employee& emp) { double total; total = salary + emp.getSalary(); return(total); } double Employee::operator+(const Employee& emp) { double total; total = salary + emp.getSalary(); return(total); }

18 Using the member functions double sum // these three statements do the same thing sum = Clerk.addTwo(Driver); sum = Clerk.operator+(Driver); sum = Clerk + Driver; // the syntax for the last one is the most natural // and is easy to remember because it is consistent // with how the + operator works for everything else

19 Operator Overloading: Restrictions zPrecedence and associativity cannot be changed zSome operators cannot be overloaded: yScope resolution :: yMember access. and.* yTernary conditional expression ?:

20 Implementing overloaded operators zThe compiler uses the types of arguments to choose the appropriate overloading. Vector v1, v2; v1 + v2; // “Vector” + string s1, s2; s1 + s2; // string “+” zOverloaded operators can be yclass methods ynon-class functions

21 Definining overloaded operators complex operator+( const complex& a, const complex& b);  keyword operator followed by operator symbol

22 Member vs. Nonmember functions zOperators may be either nonstatic members of a class or nonmembers. zWe will only use operators that are member functions. zIn fact, many operators MUST be member functions: =, (), [], ->

23 Overloading binary operators

24 Example zThe fraction class. zFractions consist of numerators and denominators. zIn addition, we might want to include data members to store a symbol (/), and perhaps even store the decimal equivalent of the fraction as a double.

25 The fraction class Class Fraction { private: static char symbol; int numerator; double floatingPoint; int denominator; double convert(); public: Fraction(const int n=0, const int d=1); Fraction(const int w, const int n, const int d); void setData(const int n, const int d); void showData(); void invertFraction(); int greatestCommon Denom(); void reduceFraction(); Fraction operator+(Fraction& f2); }

26 Overloaded operator+ Fraction Fraction::operator+(Fraction& f2) { Fraction result; int tempNum, tempDenom; tempNum = Fraction::numerator * f2.denominator + f2.numerator * Fraction::denominator; tempDenom = Fraction::denominator * f2.denominator; result.setData(tempNum, tempDenom); result.reduceFraction(); return(result); }

27 Client code (main program) #include “fraction.cpp” void main() { Fraction firstFrac(1,8), secondFrac(2,7), sum; sum = firstFrac + secondFrac; sum.showData(); } RESULT: Decimal is Fraction is 23/56

28 Overloaded operator- Fraction Fraction::operator-(Fraction& f2) { Fraction result; int tempNum, tempDenom; tempNum = Fraction::numerator * f2.denominator - f2.numerator * Fraction::denominator; tempDenom = Fraction::denominator * f2.denominator; result.setData(tempNum, tempDenom); result.reduceFraction(); return(result); }

29 Overloaded operator+ Fraction Fraction::operator*(Fraction& f2) { Fraction result; int tempNum, tempDenom; tempNum = Fraction::numerator * f2.numerator; tempDenom = Fraction::denominator * f2.denominator; result.setData(tempNum, tempDenom); result.reduceFraction(); return(result); }

30 Overloaded operator/ Fraction Fraction::operator/(Fraction& f2) { Fraction result; int tempNum, tempDenom; tempNum = Fraction::numerator * f2.denominator; tempDenom = Fraction::denominator * f2.denominator; result.setData(tempNum, tempDenom); result.reduceFraction(); return(result); }

31 Overloaded operators as class methods zAll (non-static) methods have an implicit arg Class* this zSo, unary operators that are class methods do not take any arguments zand binary operators that are class methods may need only one argument.

32 “this” pointer zEvery class has a built-in pointer “this” to the object on which a method was called zIt is available only inside methods zused for self-referencing:  this->month = month;  this is typed!  Class* const for methods of objects Class  const Class* const for const methods

33 Old version of operator+ Fraction Fraction::operator+(Fraction& f2) { Fraction result; int tempNum, tempDenom; tempNum = Fraction::numerator * f2.denominator + f2.numerator * Fraction::denominator; tempDenom = Fraction::denominator * f2.denominator; result.setData(tempNum, tempDenom); result.reduceFraction(); return(result); }

34 New version of operator+ using ‘this’ Fraction Fraction::operator+(Fraction& f2) { this->numerator = this->numerator * f2.denominator + f2.numerator * this->denominator; this->denominator = this->denominator * f2.denominator; this->setData(tempNum, tempDenom); this->reduceFraction(); return(*this); }

35 Multiple operators zOften, you may need to reference an operator more than once in a expression. zExample: ytotal = a + b + c; zBut this can cause big problems when operator overloading is involved zSee next few slides for an example

36 Client code for class Employee Void main() { Employee Clerk(115, ); Employee Driver(256, ); Employee Secretary(567, ); double sum; sum = Clerk + Driver + Secretary; cout << “Sum is “ << sum; }

37 The problem zOperator + is left to right associative, so Clerk and Driver are added. The result is a double. zNow that double is on the left and an Employee is on the right (Secretary) zBUT THE OPERATOR + is only defined for arguments of type Employee, not zoperator+(double, Employee&)

38 The problem gets worse zIt would seem that all we have to do is write another version of the overloaded operator to work with the arguments (double, Employee&) zBut… yalthough we could overload an operator to work like this: ysum = Secretary + num; zWe cannot overload one like this: ysum = num + Secretary; // why not?

39 The answer zWe cannot overload + for a double zDouble is a native type, and it is also the implicit type in this version of our function! zThe real solution is to make sure that your operator+ function never returns a double (or any other native type). zAn operator to add Employees should return an Employee (see next slide)

40 Solution example Employee Employee::operator+(const Employee& emp) { Employee total(999,0); // dummy values total.salary = this->salary + emp.salary; return(total); }

41 Final note zIt is important that the operator+ function return an Employee object rather than a reference to an Employee object. zIf it returns a pointer to total then the returned pointer would pass out of scope and cease to exist.


Download ppt "Operator overloading. Operatorsand precedence zLeft to right associative y:: scope resolution y. direct member access y-> indirect member access y[] subscripting."

Similar presentations


Ads by Google