Operator Overloading - PowerPoint PPT Presentation

1 / 73
About This Presentation
Title:

Operator Overloading

Description:

(a bi) (c di) = (a c) (b d)i (a bi) - (c di) = (a - c) (b - d)i ... i = d; // double d converted to int. f(d); // double d converted to int ... – PowerPoint PPT presentation

Number of Views:146
Avg rating:3.0/5.0
Slides: 74
Provided by: haiyan9
Category:

less

Transcript and Presenter's Notes

Title: Operator Overloading


1
SECTION 8
  • Operator Overloading

2
Operator Overloading
  • Overloading refers to the multiple meanings of
    the same name or symbol.
  • Name overloading
    overloaded function.
  • Symbol overloading
    overloaded operator.

3
Operator Overloading
  • An operator is a symbol that is used to represent
    specific operations on its operand(s).
  • e.g.
  • arithmetic operator , -, , /
  • logical operator and
  • pointer operator and
  • memory management operator new, delete
  • A binary operator is an operator that takes two
    operands a unary operator is one that takes one
    operand.

4
Operator Overloading
  • An operator can be viewed as a function name.
  • Examples
  • x y (x, y)
  • x (x)
  • Operators are an example of syntactic sugar,
    which refers to a slightly different but more
    user-friendly syntax.

5
Operator Overloading
  • Arithmetic operator such as and / are already
    overloaded in C/C for different built-in types.
  • For example, the same operator / , different
    algorithms are used to compute two types of
    divisions.
  • 2 / 3 // integer division result
    is 0
  • 2.0 / 3.0 // floating-point division
    result is 0.666667

6
Operator Overloading
  • C allows most operators to be overloaded for
    user-defined types (classes).
  • The following operators can be overloaded
  • new new delete delete
  • - /
  • ! lt gt
  • - /
  • gtgt ltlt ltlt gtgt ! lt
  • gt -- , -gt
  • -gt ()

7
Operator Overloading
  • The following can not be overloaded
  • . . ? sizeof typeid

8
Why operator overloading?
  • Overloaded operators have the appropriate meaning
    to user-defined types, therefore they can be used
    for these types just like they are used for
    built-in types.

9
Why operator overloading?
  • Example 1 use operator for adding two objects
    of user-defined type complex number.
  • include "complex_number.h"
  • complex_number x(1, 2), y(2, 3)
  • cout ltlt ( x y )
  • Example 2 compare two date objects by chronology
    of the year.
  • include "date.h"
  • Date(6, 4, 1989) lt Date(8, 15, 1999)
  • Date(4, 1, 2002) Date("4/1/2002")

10
Why operator overloading?
  • An operator must be overloaded to be used on
    class objects, but with two exceptions operator
    and operator
  • Operator and operator are overloaded
    implicitly for every class.
  • operator performs member-wise copy of the data
    members.
  • operator returns the address of the object in
    memory.

11
  • Example
  • class Myclass
  • public
  • Myclass() x(0), y(0)
  • Myclass(int xx, int yy) x(xx), y(yy)
  • private
  • int x, y
  • int main()
  • Myclass c1, c2(5,6)
  • Myclass ptr
  • c1 c2 // use overloaded
    operator
  • ptr c2 // use overloaded
    operator

12
How to overload operators?
  • We can overload operators by writing special
    kinds of functions. These functions are called
    operator function.
  • To overload operator _at_, the name of the operator
    function is operator_at_
  • These operator functions can be
  • class member function, or
  • stand-alone function.

13
Overload Operator as Class Member
  • Consider a binary operator _at_ xobj is an object
    of class X and yobj is of Y.
  • In order to use this operator _at_ as the following
  • xobj _at_ yobj
  • we define a member function operator_at_ in class X.

14
Overload Operator as Class Member
  • Overloading operator
  • To overload operator for class Myclass so that
    we can add two Myclass objects with the result
    being another Myclass object.
  • We declare a method named operator in class
    Myclass.

15
  • class Myclass
  • public
  • Myclass operator( Myclass )
  • // constructors
  • Myclass() x(0), y(0)
  • Myclass(int xx, int yy) x(xx), y(yy)
  • private
  • int x, y
  • // the operator member function
  • Myclass Myclassoperator( Myclass m )
  • return Myclass ( x m.x, y m.y )

16
Overload Operator as Class Member
  • Now, we can invoke operator, just like a regular
    class member function.
  • Myclass a, b
  • a.operator( b )
  • Since the keyword operator, this member function
    can also be invoked as
  • a b
  • Here, we add the Myclass objects a and b to
    obtain another Myclass object.

17
  • Example A complex number class.
  • A complex number is a number of the form z a
    bi. where i represents the square root of -1 a
    is the real part of z and b is the imaginary part
    of z.
  • Arithmetic operations on complex numbers are
    defined as follows
  • (a bi) (c di) (a c) (b d)i
  • (a bi) - (c di) (a - c) (b - d)i
  • (a bi) (c di) (ac bd) (ad bc)i
  • (a bi)/ (c di) (ac bd)/(c2 d2) ((bc -
    ad)/(c2 d2))i
  • Implement a class that represents complex
    numbers, overloads ,-, , / to support complex
    arithmetic and overloads equal ( ) and not
    equal (!) operator to support complex number
    comparison.

18
  • include ltiostreamgt (sam1.cpp)
  • using namespace std
  • class Complex
  • public
  • Complex()
  • Complex( double )
  • Complex( double, double )
  • void print() const
  • Complex operator( const Complex ) const
  • Complex operator-( const Complex ) const
  • Complex operator( const Complex ) const
  • Complex operator/( const Complex ) const
  • bool operator( const Complex ) const
  • bool operator!( const Complex ) const
  • private
  • double real
  • double imag

19
  • ComplexComplex()
  • real imag 0.0
  • ComplexComplex( double re )
  • real re
  • imag 0.0
  • ComplexComplex( double re, double im )
  • real re
  • imag im
  • void Complexprint() const
  • cout ltlt real ltlt " " ltlt imag ltlt "i\n"

20
  • Complex Complexoperator( const Complex u )
    const
  • Complex v( real u.real,
  • imag u.imag )
  • return v
  • Complex Complexoperator-( const Complex u )
    const
  • Complex v( real - u.real,
  • imag - u.imag )
  • return v
  • Complex Complexoperator( const Complex u )
    const
  • Complex v( real u.real - imag u.imag,
  • imag u.real real u.imag )
  • return v

21
  • Complex Complexoperator/( const Complex u )
    const
  • double abs_sq real u.real imag u.imag
  • Complex v( ( real u.real imag u.imag ) /
    abs_sq,
  • ( imag u.real - real u.imag ) / abs_sq )
  • return v
  • bool Complexoperator( const Complex u )
    const
  • return (real u.real imag u.imag)
  • bool Complexoperator!( const Complex u )
    const
  • return !(real u.real imag u.imag)

22
  • A simple test client
  • int main()
  • Complex c1( 8.8, 0 )
  • Complex c2( 3.1, -4.3 )
  • Complex c3 c1 c2
  • Complex c4 c2 - c1
  • c3.print()
  • c4.print()
  • if ( c3 c4 )
  • cout ltlt "No way!"
  • else
  • cout ltlt "You got it."

23
Overloading operator
  • Operator is used to copy each data member from
    the source object to the corresponding data
    member in the target object.
  • If user does not overload operator for a class.
    The compiler provides a default overloaded
    version that does the member-wise copying.
  • The default version is dangerous for classes
    whose data members include a pointer to
    dynamically allocated memory.
  • Note The situation here is similar to classs
    copy constructor.

24
  • Example (sam2.cpp)
  • class Vector
  • public
  • Vector( int n )
  • Vector()
  • // ...
  • private
  • int size
  • int ptr
  • VectorVector(int n)
  • size n
  • ptr new intsize
  • for ( int i0 iltsize i)
  • ptri 0

25
  • VectorVector()
  • delete ptr
  • int main()
  • Vector a(10)
  • Vector b(10)
  • //...
  • b a
  • Vector c a // !?
  • Memberwise copy is dangerous.

26
  • Solution
  • // overload for class Vector
  • class Vector
  • // ...
  • Vector operator( const Vector )
    //end of class definition
  • Vector Vectoroperator( const Vector v )
  • if (this ! v) // not assigning to myself
  • size v.size
  • delete ptr
  • if ( v.ptr ! 0 ) // not empty
  • ptr new intsize // allocate new memory
  • for ( int i0 iltsize i )
  • ptri v.ptri
  • else // empty
  • ptr 0
  • return this

27
Overloading operator
  • Note write the copy constructor, the overloaded
    assignment operator and destructor for classes
    with pointers referring to dynamically allocated
    memory(The Big Three principal )

28
Binary v.s. Unary operator
  • If we use a class member function to overload a
    binary operator, the member function has only one
    parameter.
  • Similarly, if we use a class member function to
    overload a unary operator, the member function
    has no parameters.

29
  • Example Overloading unary operator !
  • class Myclass
  • public
  • Myclass operator!() // takes no argument
  • // ...
  • private
  • int x, y
  • Myclass Myclassoperator!()
  • Myclass tmp( -x, -y )
  • return tmp
  • ...

30
Overloading the Increment andDecrement operators
  • The operator and -- have two forms pre and
    post
  • int x 6
  • x // preincrement
  • x // postincrement
  • --x // predecrement
  • x-- // postdecrement
  • To overload the preincrement and predecrement
    operator, we use the declaration
  • operator()
  • operator--()

31
Overloading the Increment andDecrement operators
  • To overload the postincrement and postdecrement
    operator, we include a dummy int parameter in the
    declaration
  • operator( int )
  • operator--( int )
  • The int is used to distinguish the post from the
    pre form.

32
  • Example (sam3.cpp)
  • include ltiostreamgt
  • using namespace std
  • class Myclass
  • public
  • void print()
  • Myclass operator( )
  • Myclass operator(int)
  • Myclass() x(0), y(0)
  • Myclass(int xx, int yy) x(xx), y(yy)
  • private
  • int x, y
  • void Myclassprint()
  • cout ltlt "x " ltlt x ltlt "y " ltlt y ltlt "\n"

33
  • Myclass Myclassoperator() // preincrement
  • x
  • y
  • return this
  • Myclass Myclassoperator(int n) //
    postincrement
  • Myclass tmp this
  • x
  • y
  • return tmp

34
  • A simple test client
  • int main()
  • Myclass a(1,1), b(1, 1), c
  • c a
  • a.print()
  • c.print() // x 1 y 1
  • c b
  • b.print()
  • c.print() // x 2 y 2

35
Overload Operator as Stand-alone Function
  • Consider a binary operator _at_ xobj is an object
    of class X and yobj is of Y.
  • To use _at_ as xobj _at_ yobj
  • we can overload operator_at_ as a stand-alone
    function which takes two parameters one of type
    X and one of type Y.
  • operator_at_ ( X, Y )

36
Overload Operator as Stand-alone Function
  • Example
  • To overload operator using a stand-alone
    function, we define the following
  • Myclass operator( Myclass x, Myclass y)
  • // ...
  • This stand-alone function operator, has two
    parameters - the two Myclass objects, and returns
    one Myclass object.

37
Overload Operator as Stand-alone Function
  • Following the usual syntax for invoking a
    function, the operator can be invoked as
  • Myclass x, y, z
  • z operator( x , y )
  • Since the keyword operator, this function can be
    invoked as
  • z x y

38
  • Consider the following implementation for
    overloading using stand-alone function is there
    a problem?
  • class Myclass
  • public
  • void print()
  • Myclass() x(0), y(0)
  • Myclass(int xx, int yy) x(xx), y(yy)
  • private
  • int x, y
  • // overload operator as stand-alone function
  • Myclass operator( Myclass c1, Myclass c2 )
  • Myclass tmp( c1.x c2.x,
  • c1.y c2.y )
  • return tmp

39
  • The operator can not access private data member
    of class Myclass.

40
  • Solution 1 Add accessor member function.
  • class Myclass
  • public
  • int getX() return x
  • int getY() return y
  • // rest omitted
  • private
  • int x, y
  • Myclass operator( Myclass c1, Myclass c2 )
  • Myclass tmp( c1.getX() c2.getX(),
  • c1.getY() c2.getY() )
  • return tmp

41
  • Solution 2 Use friend functions
  • class Myclass
  • public
  • // rest omitted
  • private
  • int x, y
  • friend Myclass operator( Myclass, Myclass )
  • // as stand-alone friend
  • Myclass operator( Myclass c1, Myclass c2 )
  • Myclass tmp( c1.x c2.x,
  • c1.y c2.y )
  • return tmp

42
Operator functionsAs class member v.s. As
stand-alone
  • Using class member functions, the overloaded
    operator is invoked as a member function on an
    object.
  • a b c
  • a b.operator( c )
  • Using stand-alone functions, the overloaded
    operator is invoked as a function that treats the
    two operands equally.
  • a operator( b , c )

43
Operator functionsAs class member v.s. As
stand-alone
  • An operator intended to accept a basic type as
    its first operand can only be overloaded as stand
    alone function.

44
Overloading the Input and Outputoperators
  • Bitwise operator gtgt ( right shift ) and ltlt ( left
    shift ) are built-in operators in C/C.
  • These two operators are overloaded in system
    library for formatted input and output of
    built-in types.

45
Overloading the Input and Outputoperators
  • Example
  • In class ostream
  • ostream operatorltlt( const char )
  • ostream operatorltlt( const int )
  • ostream operatorltlt( const char )
  • //...

46
Overloading the Input and Outputoperators
  • Since cout is an object of ostream, the following
    code
  • int i
  • char s
  • //...
  • cout ltlt i
  • cout ltlt s
  • can be interpreted as
  • cout.operatorltlt( i )
  • cout.operatorltlt( s )

47
Overloading the Input and Outputoperators
  • ltlt and gtgt can be further overloaded for
    user-defined types.
  • Question Do we overload ltlt and gtgt as stand-alone
    function or class member function?

48
  • Example
  • To overload gtgt to read into a Myclass object as
    the following
  • Myclass c
  • cin gtgt c
  • we write a stand-alone function operatorgtgt as
  • istream operatorgtgt( istream in, Myclass m)
  • return ( in gtgt m.x gtgt m.y )
  • // as friend

49
  • Thus, the statement
  • cin gtgt c
  • is now equivalent to
  • operatorgtgt( cin, c )
  • which is evaluated as
  • cin gtgt c.x gtgt c.y

50
  • Complex number class revisit
  • include ltiostreamgt
  • using namespace std
  • class Complex
  • public
  • Complex()
  • Complex( double )
  • Complex( double, double )
  • friend Complex operator( const Complex, const
    Complex )
  • friend Complex operator-( const Complex, const
    Complex )
  • friend Complex operator( const Complex, const
    Complex )
  • friend Complex operator/( const Complex, const
    Complex )
  • friend bool operator( const Complex, const
    Complex )
  • friend bool operator!( const Complex, const
    Complex )
  • friend istream operatorgtgt( istream, Complex )
  • friend ostream operatorltlt( ostream, const
    Complex )
  • private
  • double real, imag

51
  • //...
  • istream operatorgtgt( istream in, Complex c )
  • return in gtgt c.real gtgt c.imag
  • ostream operatorltlt( ostream out, const Complex
    c )
  • return out ltlt c.real ltlt " " ltlt c.imag ltlt "i" ltlt
    endl
  • int main()
  • Complex c1, c2
  • cin gtgt c1 gtgt c2
  • cout ltlt c1 ltlt c2
  • cout ltlt c1 c2

52
Overloading Operator
  • An overloaded subscript operator must be defined
    as class member function.
  • class Vector
  • public
  • // ...
  • int operator(int)
  • private
  • int v
  • int v_size
  • int Vectoroperator( int index )
  • return vindex

53
  • //...
  • Vector vec(10)
  • for( int i0 iltvec.size() i )
  • veci veci i
  • //same as vec.operator(i)vec.opera
    tor(i)i

54
Overloading Operator ()
  • An overloaded function call operator must be
    defined as class member function.

55
  • Class MyFunction
  • // ...
  • public
  • int operator()(int)
  • int MyFunctionoperator()(int x)
  • return xxx
  • //...
  • MyFunction f
  • cout ltlt f(100) //equivalent to
    coutltltf.operator() (100)
  • Here, f is an example of function object, or
    functor.

56
Rules on operator overloading
  • User can not create new operators.
  • The precedence of the operator can not be
    changed.
  • The number of operands required by the operator
    can not be changed.
  • Overload operator only when it is necessary.

57
Type Conversion
  • Implicit Conversions
  • Conversions are carried out automatically by the
    compiler.

58
Type Conversion
  • Example
  • int f(int)
  • // ...
  • int i
  • double d
  • i d // int i converted to double
  • d i // int i converted to double
  • i d // double d converted to int
  • f(d) // double d converted to int

59
Type Conversion
  • Explicit Conversions(Cast)
  • Conversions are specified by the programmer.
  • Example
  • int i, j
  • (double)i / j

60
User Defined Conversion
  • Conversion to user-defined type Use
    constructors to perform an implicit conversion.
  • Example
  • class Complex
  • public
  • Complex( double )
  • Complex( double, double )
  • //...

61
User Defined Conversion
  • void f(Complex)
  • double x
  • int y
  • f(x) // ok
  • f(y) // ok
  • We can use keyword explicit to disable
    user-defined implicit conversion

62
User Defined Conversion
  • Conversion from user-defined type
  • Use conversion functions.
  • A conversion function is a special class member
    function that defines a conversion to convert a
    class object into some other type.
  • Prototype
  • operator NEWTYPE(void)

63
  • Example
  • class Rational
  • public
  • operator double() //conversion function
  • // ...
  • private
  • long num, den
  • // ...
  • Rationaloperator double()
  • return double(num)/den
  • double x
  • Rational r(2, 3)
  • x double(r) // ok explicit conversion, same
    as r.double()
  • x r // ok implicit conversion

64
  • Example A rational number class
  • Description
  • The rational numbers are the set of quotients P/Q
    where P and Q are integers and Q can not be zero.
  • The number P is called the numerator and the
    number Q is called the denominator.

65
  • class Rational (sam4.cpp)
  • public
  • // constructors that handle conversion
  • // int -gt rational, double-rational
  • Rational( int0, int1 )
  • Rational( double )
  • // binary and unary operators
  • Rational operator (const Rational v) const
  • Rational operator- (const Rational v) const
  • Rational operator (const Rational v) const
  • Rational operator/ (const Rational v) const
  • Rational operator- () const

66
  • // relational operators
  • bool operatorlt (const Rational v) const
  • bool operatorlt (const Rational v) const
  • bool operator (const Rational v) const
  • bool operator! (const Rational v) const
  • bool operatorgt (const Rational v) const
  • bool operatorgt (const Rational v) const
  • // conversion operator rational -gt double
  • operator double() const
  • // rational number input/output
  • friend istream operatorgtgt (istream in,
    Rational v)
  • friend ostream operatorltlt (ostream out,
    Rational v)

67
  • // utility methods
  • int getNumerator() const return num
  • int getDenominator() const return den
  • void reduce()
  • private
  • void standardize() // rational unility methods
  • int gcd(int, int)
  • long num, den

68
  • //approximate double x to a rational number
  • RationalRational(double x)
  • double val1, val2
  • // move decimal part of x 8 pos to the right
  • val1 100000000L x
  • // move deciaml part of x 7 pos to the right
  • val2 10000000L x
  • // get rid of the fractional part approx x
  • num long(val1-val2)
  • den 90000000L
  • reduce()

69
  • RationalRational(int x, int y) num(x),
    den(y)
  • if ( den0)
  • cerr ltlt "Error zero denominator \n"
  • exit(1)
  • reduce()
  • Rational Rationaloperator (const Rational v)
    const
  • return Rational(numv.den denv.num,
    denv.den)
  • bool Rationaloperatorlt (const Rational v)
    const
  • return numv.den lt denv.num
  • // ...

70
  • Rationaloperator double() const
  • return double(num)/den
  • void Rationalreduce()
  • int divisor, tmpnum
  • // tmpnum is the absolute value of the numerator
  • tmpnum ( num lt 0 ) ? -num num
  • // standardize 0/1
  • if ( num 0 )
  • den 1
  • else
  • divisor gcd( tmpnum, den )
  • if ( divisor ! 1 )
  • num / divisor
  • den / divisor

71
  • istream operatorgtgt (istream in, Rational v)
  • char c // reads the speartor /
  • in gtgt v.num gtgt c gtgt v.den
  • if ( v.den 0 )
  • cerr ltlt "Error zero denominator \n"
  • exit(1)
  • v.standardize()
  • return in
  • // ...

72
Operator Overloading for ClassTemplate
  • Example
  • templatelt class T gt
  • class Matrix
  • public
  • Matrix(int,int)
  • Matrix(Matrix)
  • Matrix()
  • Matrixlt T gt operator( const Matrixlt T gt ) const
  • Matrixlt T gt operator( const Matrixlt T gt )
  • // ...
  • private
  • T _mat
  • int _m, _n

73
Operator Overloading for ClassTemplate
  • templatelt class T gt
  • Matrixlt T gt Matrixlt T gt operator(const Matrixlt
    T gt m) const
  • MatrixltTgt tmp(_m, _n)
  • for ( int i0 ilt_m i )
  • for ( int j0 jlt_n j )
  • tmp._matij m._matij _matij
  • return tmp
  • // rest omitted
Write a Comment
User Comments (0)
About PowerShow.com