Operator overloading l.jpg
Sponsored Links
This presentation is the property of its rightful owner.
1 / 25

Operator Overloading PowerPoint PPT Presentation


  • 114 Views
  • Uploaded on
  • Presentation posted in: General

Department of Computer and Information Science, School of Science, IUPUI. Operator Overloading. Dale Roberts, Lecturer Computer Science, IUPUI E-mail: [email protected] Operator Overloading .

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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Department of Computer and Information Science,School of Science, IUPUI

Operator Overloading

Dale Roberts, Lecturer

Computer Science, IUPUI

E-mail: [email protected]


Operator Overloading

  • Function-call notation is cumbersome for certain kinds of classes, especially mathematical classes

  • Allows extendable design

  • Most appropriate for math classes. eg. Matrix, Vector, etc.

  • Gives Operators Class-Specific Functionality

  • In-built or Standard Overloading for Basic Numerical Data Types -- + can be used with int, float, doubles

  • Analogous to Function Overloading -- operator@ is Used as the Function Name

  • 40 Operators can be Overloaded to Give Class-Specific Functionality

  • C++ enables programmers to overload operators to be sensitive to the context in which they are used.  The compiler generates appropriate code

  • Easier to read


Requirements of Overloaded Operators

  • Their Meaning Should be Intuitive -- + Should Mean Addition

  • When Appropriate, they Should be Associative -- a + b Should Result in an Object, c of the Same Class

  • If these Conditions are Not Satisfied then it is Better to Use Member Functions and Not Operator Overloading

  • To use an operator on class objects, that operator must be overloaded - with two exceptions - the assignment operator (=), which performs a member wise copy, and the address (&) operator


Forms of Overloaded Operators

  • Member Functions

  • Friend Functions

  • Free-Standing or Global Functions


Operator Functions

  • When to make class members, friends or global functions?

  • If member function, then this is implicitly available for one of the arguments

  • When overloading ( ), [ ], ->, or =, the operator overloading function must be declared as a class member.  For other operators, the overloading functions can be non-members

  • When an operator function is implemented as a member function, the left most (or only in the case of unary operators) operand must be a class object (or a reference to a class object) of operator's class

  • If the left operand must be an object of a different class or a built-in type, this operator must be implemented as a non-class member. eg. <<, >> operators


Operator Functions (cont)

  • An operator function implemented as a non-member must be a friend if it needs to access non-public data members of that class.

  • The overloaded << operator must have a left operand of type ostream.  Therefore, it must be a non-member function.  Also, it may require access to the private data members of the class.  Thus, it needs to be a friend function for that class.

  • Similar observation holds for >> operator which has a left operand of type istream.

  • Operator member functions are classed only when the left operand of a binary operator is specifically an object of that class or when the single operand of a unary operator is an object of that class.

  • If the operator needs to be commutative (a + b = b + a), then making it a non-member function is necessary.


Restrictions of Overloaded Operators

  • New Operators CANNOT be Created

  • Fundamental Data Types (e.g. int) CANNOT be Overloaded

  • Operator Priority CANNOT be Changed

  • Operator Associativity CANNOT be Changed

  • The arity of CANNOT be changed -- + can Take ONLY One or TWO Arguments

  • Two Separate Overloaded Functions (With Different Signatures) can be Created for Operators Which Exist in Pre-fix and Post-fix Form -- ++

  • Overloaded Operators are NOT IMPLICITLY Associative or Commutative, Even if the Original Operators were Associative or Commutative -- Associativity and Commutativity must be explicitly implemented. For Associativity this means returning an instance of the class.

  • Overloading the operator + does not automatically overload related operators (+=, ++, etc).  If needed, these related operators must be explicitly overloaded


Unary Overloaded Operators -- Member Functions

  • Invocation in Two Ways -- Object@ (Direct) or Object.operator@() (As a Function)

    class number{

    int n;

    public:

    number(int x = 0):n(x){};

    number operator-(){return number (-n);}

    };

    main()

    {

    number a(1), b(2), c, d;

    //Invocation of "-" Operator -- direct

    d = -b; //d.n = -2

    //Invocation of "-" Operator -- Function

    c = a.operator-(); //c.n = -1

    }


Binary Overloaded Operators -- Member Functions

  • Invocation in Two Ways -- ObjectA @ ObjectB (direct) or ObjectA.operator@(ObjectB) (As a Function)

    class number{

    int n;

    public:

    number(int x = 0):n(x){};

    number operator+(number ip)

    {return number (ip.n + n);}

    };

    main()

    {

    number a(1), b(2), c, d;

    //Invocation of "+" Operator -- direct

    d = a + b; //d.n = 3

    //Invocation of "+" Operator -- Function

    c = d.operator+(b); //c.n = d.n + b.n = 5

    }


Operator Overloading Using a Friend Function

  • Number of Parameters Accepted by an Overloaded Friend Operator Function Depend Upon the Operator Type -- One for Unary Operators and Two for Binary Operators

    class complex{

    int re, im;

    public:

    complex(int ip1 = 0, int ip2 = 0)

    :re(ip1), im(ip2){}

    friend complex operator+(complex, complex);

    };

    //Friend Operator + Function

    complex operator+(complex a, complex b)

    {return complex(a.re+b.re, a.im+b.im);}

    main(){

    complex one(1,1), two(2,2), three;

    three = operator+(one, two); //three = one + two

    }

Is a friend function necessary in this case?

No because LH operand is an instance of the class.


Operator Functions as Class Members vs. as friend Functions

Non-member overloaded operator functions

  • Enable the operator to be commutative

    HugeInteger bigInteger;

    int integer;

    bigInteger = integer + bigInteger;

    or

    bigInteger = biginteger + integer;


Global Operator Overloading

  • Similar to friend Function Overloading, Except the Keyword friend is Omitted and Global Functions CANNOT ACCESS private Members

    class complex{ //All Public Members!

    public:

    int re, im;

    complex(int ip1 = 0, int ip2 = 0)

    :re(ip1), im(ip2){}

    };

    void operator!(complex a)

    {

    int temp = a.re; a.re = a.im; a.im = temp;

    cout << "Real: " << a.re << endl;

    cout << "Imaginary: " << a.im << endl;

    }

    main()

    {

    complex one(1,2);

    operator!(one);

    !one;

    }


Overloading of Operators Having a Variable Arity

  • Operators Such as + and - Can be Unary or Binary

  • Overloading of Such Operators Involves Creating a Unary Function (One Operand) and a Binary Function (Two Operands)

  • Only if Both the Forms are Used, They Need to be Implemented

    class number{

    int n;

    public:

    number(int x = 0):n(x){}

    number operator-(){n = -n; return *this;}

    number operator-(number ip)

    {n = n – ip.n; return *this;}

    };

    main(){

    number one(1), two(2), three;

    one = -one; //unary operator

    three = one - two; //three.n = -3

    }


Operators with Prefix and Postfix Forms

  • Separate Functions for Each -- Prefix and Postfix -- Forms are Needed

  • Prefix Form is Treated as an Unary Operator

  • Postfix Form is Treated as a Binary Operator


Prefix Overloaded Function -- Example

class number{

int n;

public:

number(int x):n(x){}; //Constructor

//prefix operator -- unary

number operator++();

};

number number::operator++(){

n++; return *this;}

main(){

number one(10); //one.n = 10

one++; //one.n = 11

}


Postfix Overloaded Function -- Example

  • Postfix Operator is Implemented as a Binary Operator with an int Argument with a Default Value of 0 . When specifying an overloaded operator for the postfix form of the increment or decrement operator, the additional argument must be of type int; specifying any other type generates an error.

    class number{

    int n;

    public:

    number(int x):n(x){}; //Constructor

    //postfix operator -- binary -- int argument

    number operator++(int);

    };

    number number::operator++(int y)

    {if (y != 0) n += y; else n++; return *this;}

    main()

    {

    number one(10); // one.n = 10

    one++; // one.n = 11

    one.operator++(2); // one.n = 13

    }

  • There is no syntax for using the increment or decrement operators to pass these values other than explicit invocation, as shown in the preceding code. A more straightforward way to implement this functionality is to overload the addition/assignment operator (+=).


Special Overloading Forms

  • A Few Operators Require Special Treatments During Overloading

  • Conversion Operator

  • const Array Operator

  • Function Call -- Parenthesis Operator

  • Stream Insertion -- << Operator

  • Stream Extraction -- >> Operator

  • Pointer to Member -- -> Operator

  • Assignment Operator

  • new Operator

  • delete Operator


Overloading Stream-Insertion and Stream-Extraction Operators

  • Overloaded << and >> operators

    • Must have left operand of types ostream&, istream& respectively

    • It must be a non-member function (left operand not an object of the class)

    • It must be a friendfunction if it accesses private data members


1// Fig. 18.3: fig18_03.cpp

2// Overloading the stream-insertion and

3// stream-extraction operators.

4#include <iostream>

5

6using std::cout;

7using std::cin;

8using std::endl;

9using std::ostream;

10using std::istream;

11

12#include <iomanip>

13

14using std::setw;

15

16class PhoneNumber {

17friend ostream &operator<<( ostream&, const PhoneNumber & );

18friend istream &operator>>( istream&, PhoneNumber & );

19

20private:

21char areaCode[ 4 ]; // 3-digit area code and null

22char exchange[ 4 ]; // 3-digit exchange and null

23char line[ 5 ]; // 4-digit line and null

24};

25

26// Overloaded stream-insertion operator (cannot be

27// a member function if we would like to invoke it with

28// cout << somePhoneNumber;).

29ostream &operator<<( ostream &output, const PhoneNumber &num )

30{


31 output << "(" << num.areaCode << ") "

32 << num.exchange << "-" << num.line;

33return output; // enables cout << a << b << c;

34}

35

36istream &operator>>( istream &input, PhoneNumber &num )

37{

38 input.ignore(); // skip (

39 input >> setw( 4 ) >> num.areaCode; // input area code

40 input.ignore( 2 ); // skip ) and space

41 input >> setw( 4 ) >> num.exchange; // input exchange

42 input.ignore(); // skip dash (-)

43 input >> setw( 5 ) >> num.line; // input line

44return input; // enables cin >> a >> b >> c;

45}

46

47int main()

48{

49 PhoneNumber phone; // create object phone

50

51 cout << "Enter phone number in the form (123) 456-7890:\n";

52

53 // cin >> phone invokes operator>> function by

54 // issuing the call operator>>( cin, phone ).

55 cin >> phone;

56

57 // cout << phone invokes operator<< function by

58 // issuing the call operator<<( cout, phone ).

59 cout << "The phone number entered was: " << phone << endl;

60return 0;

61}


Enter phone number in the form (123) 456-7890:

(800) 555-1212

The phone number entered was: (800) 555-1212


Converting between Types

  • Cast operator

    • Convert objects into built-in types or other objects

    • Conversion operator must be a non-static member function.

    • Cannot be a friend function

    • Do not specify return type

      For user-defined class A

      A::operator char *() const; // A to char

      A::operator int() const; //A to int

      A::operator otherClass() const; //A to otherClass

    • When compiler sees (char *) s it calls

      s.operator char*()


Converting between Types (cont)

  • The compiler can call these functions to create temporary objects.

    • If s is not of type char *

      Calls A::operator char *() const; for

      cout << s;


Special overloading forms - Example

  • Special Forms Example


Acknowledgements

  • These slides were originally development by Dr. Uday Murthy and Dr. Rajeev Raje.

  • Some contents comes from the Deitel slides that accompany your text.

  • Some information regarding the postfix form the increment and decrement operators comes from MSDN.


  • Login