Download presentation
Presentation is loading. Please wait.
1
Operator Overloading Fundamentals
Methods (class members & friend functions) Binary operators Stream operators Unary operators Pre & post increment & decrement
2
Fundamentals Operator overloading is a way to use operators 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 are overloaded automatically by the compiler Assignment operator (=) Memberwise assignment of class data members Address operator (&) Returns the address of the object in memory Both can also be explicitly overloaded
4
Restrictions For a list of operators that can be overloaded
See D & D, Chapter 19.3 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
Default Memberwise Copy
Assignment operator (=) can be used to assign one object to another By default, performed by memberwise copy Each data member of one object is copied to another object’s data members Can cause problems with dynamically allocated data members (such as linked list) int main(){ Fraction f1, f2(3,4); f1 = f2; f1.print(); // 3/4 f2.print(); // 3/4 return 0; }
7
Default Memberwise Copy
If you were to write it yourself, it would look like this See complete program at assign.cpp const Fraction &operator=(const Fraction &f){ num=f.num; den=f.den; return *this; /*a pointer to the current object*/ }
8
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
9
Method #1 (see method1.cpp) c.operator=(a.operator+(b))
class Fraction { int num, den; public: Fraction(int n, int d) {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.cpp) c.operator=(a.operator+(b)) void main(){ Fraction a(1,3); Fraction b(2,3); Fraction c; c = a + b; c.print(); // 1/1 }
10
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<<fraction2)
11
Method #2 (See method2.txt) c.operator=(operator+(a, b)) void main(){
Fraction a(1,3); Fraction b(2,3); Fraction c; c = a + b; c.print(); // 1/1 } class Fraction { int num, den; public: Fraction(){num=0;den=1;} Fraction(int n, int d) {... 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))
12
Why Does This Program Run?
class Fraction { int num, den; public: Fraction(){num=0;den=1;} Fraction(int n) {num=n;den=1;} 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;} }; void main(){ Fraction a, b; a = 1 + a; b = b; a.print(); //1/1 b.print(); //2/1 } (See run.cpp)
13
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 an 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)
14
Conversion Constructor
A constructor that transforms objects of one type into objects of another type Example constructor that converts int to Fraction: Fraction(int n){num=n;den=1;}
15
Overloading Stream Operators
cin object An instance (variable) of the istream class operator>> So cin>>a>>b; becomes operator>>(cin,a); operator>>(cin,b); cout object An instance (variable) of the ostream class operator<< So cout<<a<<b; becomes operator<<(cout,a); operator<<(cout,b);
16
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.cpp)
17
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 change false to true Returns either true (non-zero) or false (zero) Use bool (boolean) data type
18
Overloading Unary Operators
As a class member function bool operator!()const{ if(0!=num){return false;} return true; } As a friend function friend bool operator!(const Fraction &f){ if(0!=f.num){return false;} } (See unary.cpp)
19
Overloading ++ & -- Preincrement Original code: ++f1;
Compiler will generate: f1.operator++(); Function prototype: Fraction &operator++(); Returns a reference to itself
20
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
21
Unary Operators class Fraction{ . . .
Fraction &operator++(){//preincrement num+=den; return *this;} Fraction operator++(int){//postincrement Fraction temp = *this; 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.cpp)
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.