Presentation is loading. Please wait.

Presentation is loading. Please wait.

Operator Overloading 1. Introduction Let’s define a class for Complex numbers: class Complex { private: double real, image; public: Complex () : real(0.0),

Similar presentations


Presentation on theme: "Operator Overloading 1. Introduction Let’s define a class for Complex numbers: class Complex { private: double real, image; public: Complex () : real(0.0),"— Presentation transcript:

1 Operator Overloading 1

2 Introduction Let’s define a class for Complex numbers: class Complex { private: double real, image; public: Complex () : real(0.0), image(0.0) {} Complex (double r) : real(r), image(0.0) {} Complex (double r,double i):real(r),image(i) {} double getReal() const {return real;} double getImage() const {return image;} void setReal(double r) {real = r;} void setImage(double i) {image = i;} }; 2 How can we make this code even simpler?

3 Example – cont. Which of the following is a valid code? 3 int x,y; x = 5; y = 6; x += y; double x,y; x = 5; y = 6; x += y; Complex x(1,1),y(1,2) ; x += y; //compiler error  We need to overload standard operators to work on user-defined types. What to do?  no match for operator+= for Complex

4 Adding ‘Complex’s – First Try Let’s add an function addComplex( const Complex& x) to our class Complex: class Complex{ … public: … void addComplex(const Complex& x) { real += x.real; image += x.image; } }; 4

5 Adding ‘Complex’s – First Try Cont 5 o The code works, but isn’t very elegant: Complex x(1,1),y(1,2); x.addComplex(y); o On the other hand, the following doesn’t work, but it’s indeed elegant: Complex x(1,1), y(1,2); x += y; o Is there anything else we can do to make the elegant code work as well?

6 Operator Overloading Operator overloading provides a more natural way to define and use operators ( +,-, etc.) for user defined types (classes and enumerations). Need to take care not to overdo it - this is a very easy way to write incomprehensible code If the users of your code need to read documentation to use your operators, you are probably doing it wrong! 6

7 Operator Overloading We overload operator OP by defining a function named operatorOP, where OP is one of the predefined C++ operators. Overloadable operators ( OP ): There exist also Non-overloadable operators. 7 &^%/*-+ ><=,!~| ==>><<--++>=<= %=/=-=+=||&&!= ()[]>>=<<=*=|=^= delete[]deletenew[]new->*->&=

8 Operator Overloading example Let’s define “+=” operator for Complex class: class Complex{ … public: void operator += (const Complex& x) { real += x.real; image += x.image; } }; Are we done here? What about: Complex n1(1,2), n2(3,4), n3; n3 += n2 += n1 ; 8

9 Operator Overloading example class Complex{ … public: Complex& operator += (const Complex& x) { real += x.real; image += x.image; return *this; } }; //usage Complex n1(1,2), n2(3,4); n1 += n2; double d = 0.0 ; n1 += d ; // OK: x.operator+=(Complex(y)) is // invoked. d += n1 ; //Error – ??? 9

10 Adding Complex Numbers //We want to be able to write: Complex x(1,1), y(2,2), z; z = x + y; //OR z.operator=(x.operator+(y)); // Thus class Complex { private: double real, image; public:... Complex operator+ (const Complex& x) const; Complex& operator= (const Complex& x); }; 10

11 Adding Complex Numbers – Cont. //Implementation: inline Complex Complex::operator+ (const Complex& num) const { return Complex(real + num.real, image + num.image); } inline Complex& Complex::operator= (const Complex& num) { real = num.real; image = num.image; return *this; } Note that the operators receive their left operand as “ this ”: z = x + y; // is translated to z.operator=(x.operator+(y)); 11

12 Operators as Non-members Operators can also be implemented as non-member functions. Overloaded “ operator- ” of A, as non- member : A operator-(const A&, const A&); Example: class Complex{ public: … //Operator “+” as member function Complex operator+(const Complex& num) const ; }; // Operator “-” as non-member function inline Complex operator-(const Complex& num1, const Complex& num2 ) { … } ; 12

13 Non Complex Right Operand How can we define operator- for: Complex – int ? Implement operator- that accepts two Complex. Requires a way of casting int to Complex (which we already have - constructor with a single parameter double ). Example: Complex x; int y; x - y; // operator-(Complex, Complex(y)) // or Complex.operator-(Complex(y)) Add overloaded operator- that accepts a single int as member function of the Complex class or operator-(const Complex&, int) as non-member function. Example: Complex x; int y; x - y; // Complex.operator-(int) // or operator-(Complex,int) 13

14 Non Complex Right Operand [1] Using implicit conversion: class Complex { … public: … Complex (double r) : real(r), image(0.0) {} Complex operator - (const Complex& rNum) const { return Complex(real-rNum.real,image-Rnum.image); } }; 14

15 Non Complex Right Operand [2] Special overload for int, member function: class Complex { … public: Complex operator - (const Complex& rNum) const; Complex operator - ( int real ) const { return *this - Complex(real) ; } }; 15

16 Non Complex Right Operand [3] Special overload for int, non-member function: class Complex { … public: Complex operator - (const Complex& rNum) const; }; inline Complex operator-( const Complex& rNum, int real) { return rNum - Complex(real) ; } 16

17 Non Complex Left Operand How can we define operator- for int – Complex ? Implement operator that can accept (int,Complex) as non-member function, by using operator-(const Complex&, const Complex&). Example: // implementation as non-member function inline Complex operator- (const int real, const Complex& rNum){ return Complex(real,0) - rNum ; } // usage Complex x ; int y ; y-x; // operator-(int,Complex) Can we implement it as a member function? 17

18 Operator Overloading: Parameters Some operators are both unary and binary (e.g. “-” ). Implemented as two functions that differ in the number of their parameters. The precedence and associativity of an operator cannot be changed. Example: Complex x(1,1), y(2,3), z ; y + z + w // y.operator+( z.operator+(w) ) x == y + z // x.operator == ( y.operator+(z) ) The number of operands, for a given operator, cannot be changed. 18

19 To Overload or Not to Overload? Overloaded operators make no guarantees about the order in which operands are evaluated.  Logical AND ( && ), logical OR ( || ), and comma (, ) operators are usually not overloaded, since all their operands, no matter what, will be always evaluated, and this in some arbitrary order!  This is opposite to intuition: the built-in versions of these operators always evaluate operands left-to-right, and logical AND/OR may not evaluate some operands at all! 19

20 To Overload or Not to Overload? If not explicitly defined, an address_of ( & ) operator for your class is synthesized by the compiler. In case we explicitly overload that operator, we lose its default implementation (override).  It is strongly recommended to avoid overloading the operator &. The same axiom holds for the “new”, “delete” and “delete[]” operators. 20

21 To Overload or Not to Overload? Do not overload operators that have no meaning for your class. For example, if you define Matrix class, you will probably overload “+” and “-” operators, but it seems strange to overload “ ” operators, since their meaning is not commonsensical. 21

22 Class Member vs. friend (1) Class member implementation (reminder): class Complex { private: … public: Complex operator+ (const Complex&) const; }; inline Complex Complex::operator+(const Complex& z) const { return Complex (real + z.real, image + z.image); } // usage: Complex x(1,1), y(2,2), z; z = x + y; 22

23 Class Member vs. friend (2) “friend” implementation: class Complex { private: … friend Complex operator+ (const Complex& z1, const Complex& z2); public: … }; inline Complex operator+ (const Complex& z1, const Complex& z2) { return Complex (z1.real+z2.real,z1.image+z2.image); } // usage: Complex x(1,1), y(2,2), z; z = x + y; //OR z.operator=(operator+(x,y)); Why do we put friend in private ? 23

24 Class Member vs. Nonmember (1) The assignment “=“, subscript “[]”, call-function “()”, and member access arrow “->” operators MUST be defined as class members. Otherwise, it is a compilation error. The compound-assignment ( +=, -=, etc.), and other operators which changes object’s state, are typically implemented as class members. Good practice is to define read-only operators as independent (non-member) functions. For example: +, -, ==, >, =,=<. 24

25 Class Member vs. Nonmember (2) Example: Complex x, z; [1] x+=z; x+=y; // OK, change their left // operand, Complex object. [2] y-z; y+x; // OK, (+,- should be implemented // as a non-member function) operator+= implementation, for example [1]: inline Complex& operator+= (const Complex& op2) { return (*this = (*this) + op2); } 25

26 Class Member vs. Nonmember (3) Input ( >> ) and Output ( << ) operators MUST be implemented as non-member functions. Why? Because the other option is to make them members of the istream/ostream classes And we cannot change these classes! 26

27 Class Member vs. Nonmember (4) class Complex { private: friend ostream& operator<<(ostream &os, const Complex & cNum ); friend istream& operator>>(istream &is, Complex & cNum ); … }; inline ostream& operator<<(ostream &os, const Complex& cNum) { return os << "(" << cNum.real << "," << cNum.image << ")"; } inline istream& operator>>(istream &is, Complex& cNum ) { is >> cNum.real >> cNum.image ; // validity check should be here return is ; } Can we implement these two as non-friends ? 27

28 Class Member vs. Nonmember (5) // implementation as non-friends: inline ostream& operator<<( ostream &os, const Complex & cNum) { os << "( " << cNum.getReal() <<", " << cNum.getImage() << " )" ; return os ; } inline istream& operator>>( istream &is, Complex & cNum ){ double tReal, tImage ; is >> tReal >> tImage ; // validity check should be here cNum.setReal( tReal ) ; cNum.setImage( tImage ) ; return is ; } 28


Download ppt "Operator Overloading 1. Introduction Let’s define a class for Complex numbers: class Complex { private: double real, image; public: Complex () : real(0.0),"

Similar presentations


Ads by Google