Presentation is loading. Please wait.

Presentation is loading. Please wait.

Andy Wang Object Oriented Programming in C++ COP 3330

Similar presentations


Presentation on theme: "Andy Wang Object Oriented Programming in C++ COP 3330"— Presentation transcript:

1 Andy Wang Object Oriented Programming in C++ COP 3330
Operator Overloading Andy Wang Object Oriented Programming in C++ COP 3330

2 Fundamentals Many existing operators that work on built-in types (e.g., int, double) Operator overloading allows programmers to define new versions of these operators A C++ operator is just a function called with special notation Overloading a function involves writing a function C++ already has operator overloading + operator works on ints, floats, doubles, and chars Different versions of + exist for each type

3 Some Rules Regarding Operator Overloading
Overloading an operator Cannot change a number of properties Precedence a + b*c Associativity (a + b) + c = a + (b + c) Number of operands Cannot create new operators Can only overload the existing ones Operator meaning on the built-in types cannot be changed

4 Some Rules Regarding Operator Overloading
In other words You can change the meaning, not the grammar That is “sick” –Big Hero 6 Yes, you can define ‘+’ as subtraction

5 Friend vs. Member Functions
Some operators can be written as member functions Some operators can be written as stand-alone friend functions A binary operator has two operands As a stand-alone function, it will take two parameters As a member function, the first operand is the calling object Taking the second operand as a parameter A unary operator has one operand As a stand-alone function, it will take a parameter As a member function, one calling object with no parameters How about “-”?

6 Format An operator is just a function
It requires a name, a return type, and a parameter list Name of an operator is always a conjunction of the keyword operator and the operator symbol operator+ operator++ operator<< operator== Format of operator overload declaration return_type operator<operator_symbol> (parameter_list);

7 Motivation Example 1 Arithmetic operators
int x = 3, y = 6, z; float a = 3.4, b = 2.1, c; z = x + y; c = a / b + 1 / 3; Can we use arithmetic operators on our Fraction class (a user-defined type)? Fraction n1, n2, n3; n3 = n1 + n2;

8 Example 1 The answer is NO Since Fraction is a user-defined type
Operator overloading makes this possible

9 Example 2 The following screen output is legal int x = 5, y = 0;
cout << x << y; How about this? Fraction f(3, 4); cout << “The fraction f = “ << f << ‘\n’; No, since the iostream library does not know about Fraction objects Again, operator overloading can help here

10 Overloading the Arithmetic Operators
Can be overloaded either as stand-alone functions or as member functions Originally, we have the following friend Fraction Add(Fraction f1, Fraction f2); To add, perform the following Fraction n1, n2, n3; n3 = Add(n1, n2);

11 Note: const is only allowed for member functions
The + Operator With operator overloading, we can have the following friend Fraction operator+(Fraction f1, Fraction f2); Or the following friend Fraction operator+(const Fraction &f1, const Fraction &f2); Thus, we can invoke the function this way n3 = operator+(n1, n2); Or, we can use the infix notation n3 = n1 + n2; // cascading also works (n1 + n2 + n3 + n4…) Note: const is only allowed for member functions

12 Definition of the + Operator
Fraction operator+(Fraction f1, Fraction f2) { Fraction r; r.numerator = (f1.numerator*f2.denominator) + (f2.numerator*f1.denominator); r.denominator = f1.denominator*f2.denominator; return r; }

13 Code Example /

14 frac.h class Fraction { friend Fraction operator+(const Fraction &f1, const Fraction &f2); public: … private: };

15 frac.cpp … Fraction operator+(const Fraction &f1, const Fraction &f2) { Fraction r; r.numerator = (f1.numerator*f2.denominator) + (f2.numerator*f1.denominator); r.denominator = f1.denominator*f2.denominator; return r; }

16 main.cpp #include <iostream> #include “frac.h” using namespace std; Int main() { Fraction f1, f2, f3(3,4), f4(6); … cout << “\n Now enter first fraction: “; f1.Input(); cout << “\nYou entered “; f1.Show(); cout << “\n Now enter first fraction: “; f2.Input(); cout << “\nYou entered “; f2.Show();

17 main.cpp cout << “\nThe sum of the first and second fraction is “; Fraction result; result = f1 + f2; result.Show(); cout << ‘\n’; cout << “Attempting arithmetic calls\n”; f2 = f1 + 5; cout << “Second arithmetic call\n”; f4 = 2 + f3; cout << “\n The fraction f1 is “; f1.Show(); … }

18 Overloading an Operator as a Member Function
Member function version of Add Fraction Add(const Fraction &f) const; To call this function Fraction n1, n2, n3; n3 = n1.Add(n2); To overload +, we can change the name Add to operator+ Fraction operator+(const Fraction &f) const; To call, either way will work n3 = n1.operator+(n2); // hardly anyone will do this n3 = n1 + n2; // n1 is the calling object, n2 is the // parameter

19 Definition of operator+
Fraction Fraction::operator+(const Fraction &f) const { Fraction r; r.numerator = (numerator*f.denominator) + (f.numerator*denominator); r.denominator = (denominator*f.denominator); return r; }

20 Example Code /

21 frac.h class Fraction { public: Fraction operator+(const Fraction &f) const; … private: };

22 frac.cpp … Fraction Fraction::operator+(const Fraction &f) const { Fraction r; r.numerator = (numerator*f.denominator) + (f.numerator*denominator); r.denominator = denominator*f.denominator; return r; }

23 main.cpp #include <iostream> #include “frac.h” using namespace std; Int main() { Fraction f1, f2, f3(3,4), f4(6); … cout << “\n Now enter first fraction: “; f1.Input(); cout << “\nYou entered “; f1.Show(); cout << “\n Now enter first fraction: “; f2.Input(); cout << “\nYou entered “; f2.Show();

24 main.cpp cout << “\nThe sum of the first and second fraction is “; Fraction result; result = f1 + f2; result.Show(); cout << ‘\n’; cout << “Attempting arithmetic calls\n”; f2 = f1 + 5; cout << “Second arithmetic call\n”; f4 = 2 + f3; // won’t work with member function cout << “\n The fraction f1 is “; f1.Show(); … }

25 Other Arithmetic Operators
Multiplication overload friend Fraction operator*(Fraction f1, Fraction f2); Operator to add a Fraction and an integer friend Fraction operator+(Fraction f, int n); // not needed Operator to add an integer to a Fraction friend Fraction operator+(int n, Fraction f); // not needed The last two operators are not needed, since we have conversion constructors

26 Friend vs. Member Operator Overloading
Will both cases work for friend version and the member function version? Fraction n1, n2, n3; n3 = n1 + 5; // case 1 n3 = 10 + n2; // case 2 What is the type of the calling object? Does it have the necessary conversion constructors?

27 Overloading Comparison Operators
Can be overloaded either as stand-alone or member functions Here is the original Equals function friend bool Equals(const Fraction &f1, const Fraction &f2); We can write this as an operator overload friend bool operator==(const Fraction &f1, const Fraction &f2); Here are the corresponding calls Fraction n1, n2; if (Equals(n1, n2)) cout << “n1 and n2 are equal”; If (n1 == n2) cout << “n1 and n2 are equal”; Hmm… Can apple == orange? Well, if we see them as fruits…

28 Can Overload All Six operator== operator!= operator< operator>

29 Overloading the Insertion << and Extraction >> Operators
<< and >> are defined for basic types Thus, the following code should not work Fraction f; cout << f; You need to teach the computer to work user-defined types

30 Overloading the Insertion << and Extraction >> Operators
<< and >> are binary operators The first operator is always an io stream object (e.g., cout) Thus, << cannot be defined as a member function Should be defined as outside (usually friend) functions The second parameter is the user-defined type Here is the overloading function friend ostream& operator<<(ostream &s, Fraction f); Or a better version friend ostream& operator<<(ostream &s, const Fraction &f);

31 Overloading the Insertion << and Extraction >> Operators
Here is the corresponding declaration for >> friend istream& operator>>(istream &s, Fraction &f); Notice that f is passed by reference Need to modify the original No const

32 Defining the Insertion << and Extraction >> Operators
Recall the Show() member function void Fraction::Show() { cout << numerator << ‘/’ << denominator; } Here is the << operator friend function for Fraction ostream& operator<<(ostream &s, const Fraction &f) { s << f.numerator << ‘/’ << f.denominator; return s; Need a return type Use s, not cout

33 Using the Insertion << and Extraction >> Operators
Member function Overloaded operator Fraction f1; cout << “f1 is “; f1.Show(); cout << ‘\n’; Fraction f1; cout << “f1 is “ << f1 << ‘\n’; // same as (((cout << “f1 is “) << f1) << ‘\n’);

34 Example with << Overload
/ How about >> overload for Fraction? Try it!

35 frac.h class Fraction { … friend ostream &operator<<(ostream &s, const Fraction &f); public: private: };

36 frac.cpp … ostream& operator<<(ostream &s, const Fraction &f) { s << f.numerator << ‘/’ << f.denominator; return s; }

37 main.cpp #include <iostream> #include “frac.h” using namespace std; int main () { Fraction f1, f2, f3(3,4), f4(6); cout << “\n The fraction f1 is “ << f1 << ‘\n’; cout << “\n The fraction f2 is “ << f2; cout << “\n The fraction f3 is “ << f3; cout << “\n The fraction f4 is “ << f4;

38 main.cpp cout << “\n Now enter first fraction: “; f1.Input(); cout << “\nYou entered “ << f1; cout << “\n Now enter second fraction: “; f2.Input(); cout << “\nYou entered “ << f2; Fraction result; result = f1 + f2; cout << “\nThe sum of the first and second fraction is “ << result << ‘\n’;

39 main.cpp cout << “\n The value of fraction 1 is “ << f1.Evaluate() << ‘\n’; cout << “\n The value of fraction 2 is “ << f2.Evaluate() << ‘\n’; cout << “Goodbyte!\n”; return 0; }

40 Another Example / Complex numbers i2 = -1 Arithmetic operators: +, -, *, / Insertion and extraction operators: <<, >> Increment and decrement: ++, --

41 Prefix vs. Postfix Notation
int j = 0; while (j < 10) { cout << ++j << endl; } // same as j = j + 1; cout << j << endl; Int j = 0; while (j < 10) { cout << j++ << endl; } // same as cout << j << endl; j = j + 1;

42 Review of Complex Numbers
(a + bi) + (c + di) = (a + c) + (b + d)i (a + bi) – (c + di) = (a – c) + (b – d)i (a + bi)(c + di) = ac + adi + bci – bd = (ac – bd) + (ad + bc)i (a + bi)/(c + di) = [(a + bi)/(c + di)][(c – di)/c – di)] = (ac – adi + bci + bd)/(c2 + d2) = (ac + bd)/(c2 + d2) + (bc – ad)i/(c2 + d2) conjugate

43 complex.h #include <iostream> using namespace std; class Complex { friend Complex operator+(const Complex &, const Complex &); friend Complex operator-(const Complex &, friend Complex operator*(const Complex &, friend Complex operator/(const Complex &,

44 Notice the return types
complex.h Notice the return types friend ostream &operator<<(ostream &, const Complex &); friend istream &operator>>(istream &, Complex &); public: Complex(double r = 0.0, double im = 0.0) // default constructor (sets to 0 + 0i) // conversion constructor (double to complex // constructor with 2 parameters (r + im*i) ~Complex(); double getReal() const; double getImaginary() const; void set(double r, double im = 0.0);

45 Just a note to the compiler to indicate that it is a postfix operator
complex.h Complex& operator++(); // prefix increment Complex operator++(int); // postfix increment Complex& operator--(); // prefix decrement Complex operator--(int); // postfix decrement private: double real, imag; }; Just a note to the compiler to indicate that it is a postfix operator

46 complex.cpp #include “complex.h” // iostream is already in complex.h Complex operator+(const Complex &c1, const Complex & c2) { return Complex(c1.real + c2.real, c1.imag + c2.imag); } Complex operator-(const Complex &c1, const Complex &c2) { return Complex(c1.real – c2.real, c1.imag – c2.image);

47 complex.cpp Complex operator*(const Complex &c1, const Complex &c2) { double realPart = c1.real*c2.real – c1.imag*c2.imag; double imagPart = c1.imag*c2.real + c1.real*c2.imag; return Complex(realPart, imagPart); } Complex operator/(const Complex &c1, const Complex &c2) { double realPart = (c1.real*c2.real + c1.imag*c2.imag) / (c2.real*c2.real + c2.imag*c2.imag); double imagPart = (c1.imag*c2.real – c1.real*c2.imag)

48 complex.cpp ostream &operator<<(ostream& os, const Complex &c) { if (c.imag = 0) return (os << c.real); if (c.real = 0) return (os << c.imag << ‘i’); os << c.real; if (c.imag > 0) os << “ + “ << c.imag << ‘i’; else os << “ – “ << -c.imag << ‘i’; return os; } // (cout << a << b << c) is the same as // (((cout << a) << b) << c) or // (((cout.operator<<(a)).operator<<(b)).operator<<(c)) // cout.operator<<(a) must return an object

49 complex.cpp // input format: <real> + <imag>i istream &operator>>(istream &is, Complex &c) { char symbol, iMarker; is >> c.real >> symbol >> c.imag >> iMarker; if (symbol == ‘ – ‘) c.imag = -c.imag; return is; } Complex::Complex(double r, double im) { real = r; imag = im; } Complex::~Complex(); double Complex::getReal() const { return real; } double Complex::getImaginary() const { return imag; } void Complex::set(double r, double im) { real = r; imag = im; }

50 complex.cpp // prefix increment Complex &Complex::operator++() { real++; return *this; } // postfix increment Complex Complex::operator++(int) { Complex temp = *this; real++; return temp; // return OLD value } // prefix decrement Complex &Complex::operator--() { real--; return *this; } // postfix decrement Complex Complex::operator--(int) { Complex temp = *this; real--;

51 samplemain.cpp #include “complex.h” using namespace std; void PrintComplex(const char* label, Complex c) { cout << label << “: “ << c << ‘\n’; } int main() { Complex c1, c2(7.5), c3(3.6, 2.1), c4(5, -8), c5(0, 8.4), c6(0, -9.3); PrintComplex(“c1”, c1); … PrintComplex(“c6, c6);

52 samplemain.cpp cout << “Enter new value for c1: “; cin >> c1; cout << “Enter new value for c2: “; cin >> c2; cout << “\nYou entered: \n”; PrintComplex(“c1”, c1); PrintComplex(“c2”, c2); }


Download ppt "Andy Wang Object Oriented Programming in C++ COP 3330"

Similar presentations


Ads by Google