Andy Wang Object Oriented Programming in C++ COP 3330

Slides:



Advertisements
Similar presentations
Engineering Problem Solving With C++ An Object Based Approach Additional Topics Chapter 10 Programming with Classes.
Advertisements

Operator overloading redefine the operations of operators
Chapter 11 Operator Overloading; String and Array Objects Chapter 11 Operator Overloading; String and Array Objects Part I.
 2003 Prentice Hall, Inc. All rights reserved. 1 Chapter 8 - Operator Overloading Outline 8.1 Introduction 8.2 Fundamentals of Operator Overloading 8.3.
Overloading Operators Overloading operators Unary operators Binary operators Member, non-member operators Friend functions and classes Function templates.
Operator Overloading Fundamentals
Operator Overloading Programming in C++ Fall 2008 Dr. David A. Gaitros
Rossella Lau Lecture 10, DCO10105, Semester B, DCO10105 Object-Oriented Programming and Design  Lecture 10: Operator overload  Operator overload.
Operator Overloading in C++ Systems Programming. Systems Programming: Operator Overloading 22   Fundamentals of Operator Overloading   Restrictions.
CMSC 2021 Stream I/O Operators and Friend Functions.
Operator OverloadingCS-2303, C-Term Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The C Programming Language,
Operator Overloading 1. Introduction Let’s define a class for Complex numbers: class Complex { private: double real, image; public: Complex () : real(0.0),
Operator overloading Object Oriented Programming.
Data Structures Using C++1 Chapter 2 Object-Oriented Design (OOD) and C++
Object Oriented Programming in C++ Chapter5 Operator Overloading.
CSC241 Object-Oriented Programming (OOP) Lecture No. 10.
Case Study - Fractions Timothy Budd Oregon State University.
Operatorsand Operators Overloading. Introduction C++ allows operators to be overloaded specifically for a user-defined class. Operator overloading offers.
Operator Overloading Version 1.0. Objectives At the end of this lesson, students should be able to: Write programs that correctly overload operators Describe.
Engineering H192 - Computer Programming Gateway Engineering Education Coalition Lect 25P. 1Winter Quarter C++: I/O and Classes Lecture 25.
Copyright  Hannu Laine C++-programming Part 4: Operator overloading.
Computer Science Department CPS 235 Object Oriented Programming Paradigm Lecturer Aisha Khalid Khan Operator Overloading.
Concordia University Department of Computer Science and Software Engineering Click to edit Master title style ADVANCED PROGRAM DESIGN WITH C++ Part 9:
Chapter 8 Operator Overloading, Friends, and References.
CPSC 252 Operator Overloading and Convert Constructors Page 1 Operator overloading We would like to assign an element to a vector or retrieve an element.
 2008 Pearson Education, Inc. All rights reserved Operator Overloading.
Slide 1 Chapter 8 Operator Overloading, Friends, and References.
Chapter 11 Friends and Overloaded Operators. Introduction to function equal // Date.h #ifndef _DATE_H_ #define _DATE_H_ class CDate { public: CDate();
LECTURE LECTURE 13 Operator Overloading Textbook p.203—216 Today: const member functions Overloading Operators Postfix/infix increment.
CS Object Oriented Programming Using C++
Operator Overloading. Binary operators Unary operators Conversion Operators –Proxy Classes bitset example Special operators –Indexing –Pre-post increment/decrement.
By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.
Learning Objectives Fundamentals of Operator Overloading. Restrictions of Operator Overloading. Global and member Operator. Overloading Stream-Insertion.
1 CSC241: Object Oriented Programming Lecture No 08.
Dale Roberts Operator Overloading Dale Roberts, Lecturer Computer Science, IUPUI Department of Computer and Information Science,
Friend Functions. Problem u Assuming two Complex objects u How would one add two numbers? W + X Complex operator+(const Complex& w, const Complex& x);
 Binary operators  Unary operators  Conversion Operators  Proxy Classes (simulating a reference) ▪ bitset example  Special operators  Indexing 
Operator Overloading What is operator overloading? Most predefined operators (arithmetic, logic, etc.) in C++ can be overloaded when applied to objects.
Object Oriented Programming COP3330 / CGS5409.  Arithmetic Operator Overloading  Increment (++) / Decrement (--)  In-class exercise.
Operator Overloading.
Chapter 18 - C++ Operator Overloading
CSE1002 – Problem Solving with Object Oriented Programming
Operator Overloading CS 3370 – C++ Chapter 14.
Operator Overloading Introduction
COMP 53 – Week Two Operator Overloading.
Reference Parameters There are two ways to pass arguments to functions: pass- by-value and pass-by-reference. pass-by-value A copy of the argument’s value.
Chapter 1.2 Introduction to C++ Programming
Department of Computer and Information Science, School of Science, IUPUI Operator Overloading Dale Roberts, Lecturer Computer Science, IUPUI
Operator Overloading; String and Array Objects
Andy Wang Object Oriented Programming in C++ COP 3330
Computing Fundamentals
Visit for more Learning Resources
Object Oriented Programming COP3330 / CGS5409
Object-Oriented Design (OOD) and C++
Operator Overloading Part 2
Polymorphism in C++ Operator Overloading
Andy Wang Object Oriented Programming in C++ COP 3330
Andy Wang Object Oriented Programming in C++ COP 3330
Operator Overloading; String and Array Objects
Operator Overloading.
Advanced Program Design with C++
Operator Overloading; String and Array Objects
Chapter 6: UNDERSTANDING FRIENDS AND OVERLOADING OPERATORS
Operator Overloading, Friends, and References
Operator Overloading.
Operator Overloading.
CISC/CMPE320 - Prof. McLeod
Operator Overloading Professor Hugh C. Lauer CS-2303, System Programming Concepts (Slides include materials from The C Programming Language, 2nd edition,
COP 3330 Object-oriented Programming in C++
Operator Overloading; String and Array Objects
Presentation transcript:

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

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

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

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

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 “-”?

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);

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;

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

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

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);

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

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; }

Code Example http://www.cs.fsu.edu/~myers/cop3330/examples/oo/frac1 /

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

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; }

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();

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(); … }

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

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; }

Example Code http://www.cs.fsu.edu/~myers/cop3330/examples/oo/frac2 /

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

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; }

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();

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(); … }

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

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?

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…

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

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

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);

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

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

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’);

Example with << Overload http://www.cs.fsu.edu/~myers/cop3330/examples/oo/frac3 / How about >> overload for Fraction? Try it!

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

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

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;

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’;

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; }

Another Example http://www.cs.fsu.edu/~myers/cop3330/examples/complex / Complex numbers i2 = -1 Arithmetic operators: +, -, *, / Insertion and extraction operators: <<, >> Increment and decrement: ++, --

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;

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

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 &,

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);

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

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);

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)

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

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; }

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--;

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);

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); }