Download presentation
Presentation is loading. Please wait.
Published byEmma Horn Modified over 8 years ago
1
Operator Overloading Moshe Fresko Bar-Ilan University Object Oriented Programing 2007-2008
2
Operator Overloading Operator overloading is a more elegant way of making function calls. Syntactically different from function calls. The parameters do not appear inside parenthesis, but next to operator characters. Everything you do with operator overloading you can do with regular function calls. Example: t = x+y*z ; Here we have three binary operators called =, +, *
3
Operator Overloading - Syntax It is defined as function: operator@where @ is the operator The number of parameters depend: Class member operator functions: Binary operators have one parameter Unary operators have zero parameter Global operator functions: Binary operators have two parameters Unary operators have one parameter Example: x = y ; // x.opearator=(y) or operator=(x,y) ! x ;// x.operator!() or operator!(x)
4
Operator Overloading - Example #include using namespace std; class Integer { private:int i; public:Integer(int ii) : i(ii) {} const Integer operator+(const Integer& rv) const {cout << "operator+" << endl; return Integer(i + rv.i);} Integer& operator+=(const Integer& rv) {cout << "operator+=" << endl; i += rv.i; return *this; } }; int main() { cout << "built-in types:" << endl; int i = 1, j = 2, k = 3; k += i + j; cout << "user-defined types:" << endl; Integer ii(1), jj(2), kk(3); kk += ii + jj; }
5
Unary Operators + X - X ~X &X !X ++X X++ --X X--
6
Unary Operators – As Global Functions #include using namespace std; class Integer { long i; Integer* This() { return this; } public: Integer(long ll = 0) : i(ll) {} friend const Integer& operator+(const Integer& a); friend const Integer operator-(const Integer& a); friend const Integer operator~(const Integer& a); friend Integer* operator&(Integer& a); friend int operator!(const Integer& a); // Prefix: friend const Integer& operator++(Integer& a); friend const Integer& operator--(Integer& a); // Postfix: friend const Integer operator++(Integer& a, int); friend const Integer operator--(Integer& a, int); };
7
Unary Operators – As Global Functions // Global operators: const Integer& operator+(const Integer& a) { return a; } const Integer operator-(const Integer& a) { return Integer(-a.i); } const Integer operator~(const Integer& a) { return Integer(~a.i); } Integer* operator&( Integer& a) { return a.This(); } int operator!(const Integer& a) { return !a.i; } // Prefix: const Integer& operator++(Integer& a) { a.i++; return a; } const Integer& operator--(Integer& a) { a.i--; return a; } // Postfix: const Integer operator++(Integer& a, int) { Integer before(a.i); a.i++; return before; } const Integer operator--(Integer& a, int) { Integer before(a.i); a.i--; return before; }
8
Unary Operators – As Member Functions class Byte { unsigned char b; public: Byte(unsigned char bb = 0) : b(bb) {} const Byte& operator+() const { return *this; } const Byte operator-() const { return Byte(-b); } const Byte operator~() const { return Byte(~b); } Byte operator!() const { return Byte(!b); } Byte* operator&() { return this; } // Prefix const Byte& operator++() { ++b; return *this; } const Byte& operator--() { --b; return *this; } // Postfix const Byte operator++(int) { Byte before(b); b++; return before; } const Byte operator--(int) { Byte before(b); --b; return before; } };
9
Binary Operators – As Global Functions class Integer { long i; public: Integer(long ll = 0) : i(ll) {} // Operators: + - * / % ^ & | > friend const Integer operator+ (const Integer& left, const Integer& right); // Operators: += -= *= /= %= ^= &= |= >>= <<= friend Integer& operator+= ( Integer& left, const Integer& right); // Operators: == != = && || friend int operator== (const Integer& left, const Integer& right); } // In CPP const Integer operator+ (const Integer& left, const Integer& right) { return Integer(left.i + right.i); } Integer& operator+=(Integer& left, const Integer& right) { left.i += right.i; return left; } int operator==(const Integer& left, const Integer& right) { return left.i == right.i; }
10
Binary Operators – As Global Functions class Byte { unsigned char b; public: Byte(unsigned char bb = 0) : b(bb) {} // Operators: + - * / % ^ & | > const Byte operator+(const Byte& right) const { return Byte(b + right.b); } // Operator = only can be a member function Byte& operator=(const Byte& right) { if(this == &right) return *this; b = right.b; return *this; } // Operators: += -= *= /= %= ^= &= |= >>= <<= Byte& operator+=(const Byte& right) { b += right.b; return *this; } // Conditional operators return true/false: // Operators: == != = && || int operator==(const Byte& right) const { return b == right.b; } };
11
Unary ++ and -- Operators ++ and – – operators present may appear as Prefix : Before the variable : ++a Postfix : After the variable : a— When the compiler sees pre-increment/decrement : ++a : Compiler generates a call to operator++(a) or a.operator++() post-increment/decrement : a– Compiler generates a call to operator++(a, int) or a.operator++(int)
12
Arguments and Return Values For any argument that will not be changed Pass a const reference, for example in binary +, or < For a member function make it a const member function. ( Not with += or = ) Return value (might be anything). Return value may be a new value. (operator+ returns const value) Assignment operators modify the lvalue. They may be modified in chain. So they must return non-const reference. Logical operators must return an int (or bool) Return value optimization return Integer(left.i + right.i) Instead of Integer tmp(left.i + right.i); return tmp;
13
Comma Operator Operator Comma (,) is called when it is written explicitly to a list of values (not in a function call) #include using namespace std; class After { public: const After& operator,(const After&) const { cout << "After::operator,()" << endl; return *this; } }; class Before { }; Before& operator,(int, Before& b) { cout << "Before::operator,()" << endl; return b; } int main() { After a, b; a, b; // Operator comma called Before c; 1, c; // Operator comma called }
14
Operator –> Pointer Dereference Generally used when you want to make an object appear to be a pointer. (Like smart pointers, auto pointers) A pointer dereference operator must be a member function. It must return an object (or reference to an object) that also has a pointer dereference operator, or a pointer.
15
Operator –> Example class AutoPtr { private: Integer* myPtr; public: AutoPtr(Integer *ptr=0) : myPtr(ptr) { } AutoPtr(AutoPtr& right) : myPtr(right.release()) { } AutoPtr& operator=(AutoPtr& right) { reset(right.release()); return (*this); } ~AutoPtr(){ delete myPtr; } Integer& operator*() const { return (*get()); } Integer* operator->() const { return (get()); } Integer* get() const { return (myPtr); } Integer* release() { Integer* tmp = myPtr; myPtr = 0 ; return (tmp); } void reset(Integer* ptr = 0) { if (ptr != myPtr) delete myPtr; myPtr = ptr; } };
16
Non-member operators Global operator functions can have different argument types. operator[] gets an integer the index of the aggregate #include using namespace std; class IntArray { enum { sz = 5 }; int i[sz]; public: IntArray() { memset(i, 0, sz* sizeof(*i)); } int& operator[](int x) { return i[x]; } friend ostream& operator<<(ostream& os, const IntArray& ia); friend istream& operator>>(istream& is, IntArray& ia); }; ostream& operator<<(ostream& os, const IntArray& ia) { for(int j = 0; j < ia.sz; j++) { os << ia.i[j]; if(j != ia.sz -1) os << ", "; } os << endl; return os; } istream& operator>>(istream& is, IntArray& ia) { for(int j = 0; j < ia.sz; j++) is >> ia.i[j]; return is; }
17
Examples 1. Define a String class 1. With + and += operators 2. Copy constructor and operator= 3. Try to define it with Reference count 2. IntArray: 1. Define class IntArray a dynamic integer array. 2. Define operator= 3. Define operator+ and += meaning that the elements are added to the end 4. Define operator[] and operators << with ostream. 5. Define ++/-- meaning that to every element a 1/-1 is added 3. Smart Pointer 1. Define class Integer and add function getValue() 2. Define class SmartIntegerPointer that keeps a pointer to Integer 4. Smart Pointer with Reference Count Try to solve 2 with not re-creating new pointers in every copying.
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.