1 / 21

Operator Overloading

Operator Overloading Fundamentals Methods (class members & friend functions) Binary operators Stream operators Unary operators Pre & post increment & decrement Fundamentals Operator overloading = using the same operator for different data types

benjamin
Download Presentation

Operator Overloading

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Operator Overloading • Fundamentals • Methods (class members & friend functions) • Binary operators • Stream operators • Unary operators • Pre & post increment & decrement

  2. Fundamentals • Operator overloading = using the same operator for different data types • For example, “+” is used to add int, float, double, etc. • Function definition is written the same as any other function • Except function name becomes “operator” followed by the symbol that you are overloading • operator+

  3. Built-in Operators • A few operators don’t have to be explicitly overloaded (done automatically) • Assignment operator (=) • Memberwise assignment of class data members • Address operator (&) • Returns the address of the object in memory • Both can be explicitly overloaded

  4. Restrictions • For a list of operators that can be overloaded • See D & D, p. 670 • Five operators cannot be overloaded • ., .*, ::, ?:, sizeof • These properties cannot be changed • Precedence: * has higher precedence than + • Associativity: (a + b) + c = a + (b + c) • Arity: number of operands that the operator takes (unary & binary operators)

  5. Restrictions • Only existing operators can be overloaded • Overloading an assignment operator and an addition operator will not automatically overload the += operator F1 = F2 + F3; F1 += F2; • Misuse • Overloading the “+” operator to subtract

  6. Method #1 • Class Members: overloading an operator by adding another method (member function) to the class itself • Must use this method for overloading (), [], -> or any of the assignment operators • Can use this method when the leftmost operand is a class object • This works fine with f1 = f2 + 2; which converts “2” to a fraction (via a conversion constructor) and adds it to f2 • But will not work with f1 = 2 + f2; since “2” is not of class fraction

  7. Method #1 void main(){ Fraction a(1,3); Fraction b(2,3); Fraction c; c = a + b; c.print(); } class Fraction { int num, den; public: Fraction(int n=0, int d=1) :num(n),den(d){} Fraction operator+ (const Fraction &f){ Fraction temp; temp.num=num*f.den+f.num*den; temp.den=den*f.den; return temp;} void print() const{ cout<<num<<'/'<<den<<endl;} }; Note: c=a+b is interpreted as (see method1.txt) c.operator=(a.operator+(b))

  8. Method #2 • Friend Functions: overloading an operator as a friend function (non-member function) of the class • Can use this method when the leftmost or rightmost operand is a class object • This will fix our problem when we have a different class object on the left side of an operator • Must use this method when the leftmost operand is NOT a class object (for example, cout<<f)

  9. Method #2 void main(){ Fraction a(1,3); Fraction b(2,3); Fraction c; c = a + b; c.print(); } class Fraction { int num, den; public: Fraction(int n=0, int d=1) :num(n),den(d){} friend Fraction operator+ (const Fraction &a, const Fraction &b){ Fraction temp; temp.num=a.num*b.den+b.num*a.den; temp.den=a.den*b.den; return temp;} void print() const{ cout<<num<<'/'<<den<<endl;} }; Note: c=a+b is interpreted as (See method2.txt) c.operator=(operator+(a, b))

  10. Why Does This Program Run? void main(){ Fraction a, b; a = a + 1; b = 2.5 + b; a.print(); //1/1 b.print(); //2/1 } (See run.cpp) class Fraction { int num, den; public: Fraction(int n=0, int d=1) :num(n),den(d){} friend Fraction operator+ (const Fraction &a, const Fraction &b){ Fraction temp; temp.num=a.num*b.den+b.num*a.den; temp.den=a.den*b.den; return temp;} void print() const{ cout<<num<<'/'<<den<<endl;} };

  11. Because… • C++ will try and convert types to perform operations requested • Asks: Can I convert an “int” to a Fraction? • Yes, we have a constructor that takes and integer and returns the equivalent Fraction • System invokes constructor to build Fraction from int • What about “Fraction = double + Fraction? • Affirmative. Can convert double to int (truncate) • Can then convert int to Fraction (constructor)

  12. Conversion Constructor • A constructor that transforms objects of one type into objects of another type • Write a constructor that will convert a double into a fraction (exercise1.txt)

  13. Overloading Stream Operators • cin object • An instance of the istream class • operator>> • So cin>>a>>b; becomes • operator>>(cin,a); operator>>(cin,b); • cout object • An instance of the ostream class • operator<< • So cout<<a<<b; becomes • operator<<(cout,a); operator<<(cout,b);

  14. Stream Operators class Fraction{ . . . friend istream & operator>>(istream &in, Fraction &f){ char ch; in>>f.num>>ch>>f.den; return in;} friend ostream & operator<<(ostream &out, const Fraction & f){ out<<f.num<<'/'<<f.den; return out;} }; int main(){ Fraction a,b; cin>>a>>b; cout<<a<<" "<<b<<endl; return 0; } (See stream.txt)

  15. Overloading Unary Operators • Can be overloaded as a class member or as a friend function • For example, the logical not operator (!) • Will change true to false or false to true • Returns either true (non-zero) or false (zero) • Use bool (boolean) data type

  16. Overloading Unary Operators • As a class member bool operator!() const; bool Fraction::operator!()const{ if(num) return false; return true; } • As a friend function friend bool operator!(const Fraction &); bool operator!(const Fraction &f){ if(f.num) return false; return true; } (See unary.txt)

  17. Overloading ++ & -- • Preincrement • Original code: ++f1; • Compiler will generate: f1.operator++(); • Function prototype: Fraction &operator++(); • Returns a reference to itself

  18. Overloading ++ & -- • Postincrement • Original code: f1++; • Compiler will generate: f1.operator++(0); • This is a “dummy value” to distinguish it from preincrement • Function prototype: Fraction operator++(int); • Value return, not a reference return

  19. Unary Operators class Fraction{ . . . Fraction &operator++(){//preincrement num+=den; return *this;} Fraction operator++(int){//postincrement Fraction temp = *this; num+=den; return temp;} }; void main(){ Fraction a,b,c; b = ++a; //b.operator=(a.operator++()) c = a++; //c.operator=(a.operator++(0)) cout<<a<<" "<<b<<" "<<c<<endl; } (see prepost.txt)

  20. Use of const • Why use const at the beginning of a function? • When that function returns a reference, the user may have direct access to the object’s data members • See const.txt

  21. Class Exercise • What is the output of the following program (exercise2.txt)?

More Related