24
C++ Operator Overloading Source: How to C++ by Deitel & Deitel More notes available at: http://cplusplus- naturally.blogspot.com/

C++ Operator Overloading

Embed Size (px)

Citation preview

Page 1: C++ Operator Overloading

C++

Operator Overloading

Source: How to C++ by Deitel & Deitel

More notes available at:http://cplusplus-naturally.blogspot.com/

Page 2: C++ Operator Overloading

Introduction• Operator overloading is the process of enabling existing

C++’s operators to work with class objects. Contributes to C++’s extensibility

• Examples:– << bitwise left-shift operator and stream insertion

operator– >> bitwise right-shift operator and stream extraction

operator– + & - overloaded to perform differently depending on

their context in integer, floating-point arithmetic and pointer arithmetic

• In C++, most operators can be overloaded to be sensitive to the context in which they are used. The compiler generates the appropriate code based on the manner in which the operator is used.Compiler can distinguish between overloaded functions by looking at the data type of their arguments.

• Operator overloading has clearer notion than corresponding explicit functions calls

• Avoid excessive or inconsistent use of operator overloading as this can make program cryptic and difficult to program Use when usage is obvious – similar meaning & same syntax.

Page 3: C++ Operator Overloading

Introduction – Contd…• C++ is type-focus and type-sensitive. It is operator rich

language – built-in & those defined to work with user-defined classes.

• Prototype:Return type operator<operator-to-be-overloaded>(parameter

list)

{ … }

type if not ‘void’ then– Create a temp object (if object to be returned) to use as

return value.– Use nameless initialized temp object (return

counter(count))– Return original object using ‘this’

• To use an operator on class objects, that operator must be overloaded – with two exceptions

• Operators ‘=‘ and ‘&’ can be used with any class without explicit overloading. The default behaviour of ‘=‘ is member-wise assignment and ‘&’ is used to return address of the object in memory.

Page 4: C++ Operator Overloading

Introduction Contd…• Overloading is most appropriate for mathematical

classes. These often require that a substantial set of operators be overloaded to ensure consistency with the way these mathematical classes are handled in the real world. For e.g. a complex number class must have other operators besides addition.

• Choice of operator overloading depends on meaning & context of each operator.

• Operator overloading functions can be – member functions, friend functions & rarely, non-member non-friend functions

• Overload operators to perform the same function or similar functions on the class objects as the operators perform on objects of built-in types. Avoid non-intuitive use of operators

• Before overloading consult the manuals for compiler restrictions & requirements unique to particular objects.

Page 5: C++ Operator Overloading

Restrictions On Operator Overloading• Following operators cannot be overloaded:

– .*– ::– ?:– Sizeof

• Attempting to overload a non-overloadable operator is syntax error.

• Operator overloading cannot change operator’s:– Precedence: However, order of evaluation can be

changed using paranthesis– Associativity– Arity: Operators (&,*,+,-) have unary & binary versions;

thse can be overloaded separately.

• It is not possible to create new operators; only existing operators can be overloaded. Attempting to do so is a syntax error. Therefore, ** can be overloaded for exponentiation.

• Attempting to modify how an operator works with objects of built-in types is a syntax error.

• Binary operator cannot be overloaded to be unary

Page 6: C++ Operator Overloading

Restrictions On Operator Overloading …

• Operator overloading works only with objects of user-defined types or with a mixture of an object of a user-defined type and an object of a built-in type.

• Atleast one argument of an operator function must ne class object or a reference to a class object. This prevents programmers from chnaging how operators work on built-in types

• Assuming that overloading an operator such as ‘+’ overloads related operators such as ‘+=‘ or that overloading ‘==‘ overloads ‘!=‘ is error. Operators can be overloaded only explicitly, there is no implicit overloading

• To ensure consistency among related operators, use one to implement the others (ie use an overloaded ‘+’ operator to implement an overloaded ‘+=‘ operator).

Page 7: C++ Operator Overloading

Operator Functions as Class Members Vs Friend Functions

• Non member functions are made friends for performance reasons.

• In case of binary operators, member functions use ‘this’ pointer implicitly to obtain one of their class object arguments (the left argument for binary operator)

• In case of non-member functions, both class arguments must be explicitly listed in call

• When overloading (), [], , or any assignment operators, the operator overloading function must be declared as class member.

• For other operator, the operator overloading functions can be non-member functions

• When an operator function is implemented as a member function (the leftmost (or only) operand must be a class (or a reference to a class object) of the operators’ class

Page 8: C++ Operator Overloading

Operator Functions as Class Members Vs Friend Functions …

• If the left operand must be an object of a different class or built-in type, this operator function must be implemented as a non-member function. For e.g. ‘<<‘ or ‘>>’

• A non-member operator function needs to be friend if that function must access private or protected members of that class directly

• If non-member functions used for operator overloading are not friend functions then set/get functions may be used. The overhead of calling these functions could cause poor performance, so these functions can be inlined to improve performance.

• Operator member functions of a specific class are called only when the left operand of a binary operator is specifically an object of that class, or when the angle operand of a unary operator is an object of that class

• Use non-member operator overloading function to enable the operator to be commutative. For e.g. if we overload ‘+’ as member function ten for using it with ‘long int class object Huge integer Object’, left operand must be object of that class. So, to make it commutative, overload the operator as a non-member friend function to allow HugeInteger to appear on the right of the addition.

Page 9: C++ Operator Overloading

Overloading Stream Insertion & Stream Extraction Operator

• These operators are overloaded (in class libraries provided with C++ compilers) to process each built-in data type including C-like char* string & Pointers

• They can also be overloaded to perform i/o operations for user defined types

• E.g. of overloading >> & << for PhoneNumber class

• // Why not member function

• These operators must be non-members because object of class appears in each case as the right operand must appear on the left of the operator to overload that operator as a member function.

Page 10: C++ Operator Overloading

Overloading Unary Operators

• A unary operator for a class can be overloaded as a non-static member function with no arguments or as a non-member function with one argument; that argument must be either an object of the class or a reference to an object of the class.

• Non-static so that they can access non-static data members because static member functions can only access static data members of the class

• E.g. overloading ! Operator for class string to check if empty & return a bool result

• Case 1: Non-static member function with no arguments– !s is converted into s.operator!() is invoked

Class string {

public:

bool operator !() const;

….

};

– Operator is used on the object of which it is a member

Page 11: C++ Operator Overloading

Overloading Unary Operators …

• Case 2:Non-member function with one argument (Object copy / Object reference)

!s operator!(s)class string{friend bool operator(const string &)…};

• When overloading unary operator it is preferable to make the operator function class member instead of non-member friend function.

• Friend function and friend classes must be avoided unless they are absolutely necessary. The friend usage violates the use of encapsulation of a class.

Page 12: C++ Operator Overloading

Overloading Binary Operators

• The argument on the LHS of operator is the object of which operator is a member function. The object on the RHS must be furnished as an argument to operator. Returned value may be assigned or used in any other ways. Overloaded operator always require on less argument than its number of operands.

• Overloading as non-static member function with one argument

y+=z operator+=(z)

const string &operator +=(const string &);

• Non-member function with two arguments (one of them needs to be either a class object or a reference to a class object)

y+=z operator+=(y, z)

friend const string &operator +=(string &, const string &);

Page 13: C++ Operator Overloading

Case Study: An Array Class

• Arrays in C++ just an alternative to pointers so, arrays have much potential for errors.

• For arrays, C++ does not provide such capabilities like– Subscript range checking– Two arrays comparison with equality/relational operators– When an array is passed to a general purpose function

designed to handle arrays of any size, the size of the array must be passed as an additional argument.

– One array cannot be assigned to another with assignment operator (s) (because array names are const pointers & a const pointer cannot be used on LHS of assignment operator.

• But C++ does provide means to implement these capabilities through the mechanisms of operator overloading.

• //array example

• Subscript operator [] can be used to select elements from container classes like linked lists, strings, dictionaries etc. Also, subscripts no longer have to be integer; they can be characters, strings, floats or even objects of user-defined classes

Page 14: C++ Operator Overloading

Case Study: An Array Class …

• Copy constructor must use call-by-reference not call-by-value. Otherwise, the copy constructor call results in infinite recursion (a fatal logical error) because for call-by-value a copy of the object passed to the copy constructor must be made, which results in copy constructor being called recursively. A copy constructor is used to initialize an object with another object of same class…(to be completed from chapter highlights)

• If the copy constructor simply copied the pointer in the source object to the target object’s pointer, then both objects would point to the same dynamically allocated storage. The first destructor to execute would then delete the dynamically allocated storage & the other object’s pointer would then be undefined, a situation called a “dangling pointer” & likely to result in serious run-time error.

• A constructor, a destructor, an overloaded assignment operator and a copy constructor usually provided as a group of any class that uses dynamically allocated memory. Not providing an overloaded assignment operator and a copy constructor for such a class is a syntax error.

Page 15: C++ Operator Overloading

Case Study: An Array Class …

• Declaring assignment operator as private prevents one class object being assigned to another.

• Making overloaded assignment operator & copy constructor private prevents class objects from being copied

• Self assignment of objects is dangerous because …

• Multiple Overloading: If in same program with multiple classes having same operator being overloaded then C++ can select correct function to carry out “addition” based on type of operand.

Page 16: C++ Operator Overloading

Converting between Types

• Conversion is required in assignments, in calculations, in passing values to functions & in returning values from functions.

• Compilers know how to perform certain conversions among built-in types. This implicit conversion is done through built-in routines. Can also convert if user-defined objects are same on both sides.

• For conversion among user-defined types & built-in types, conversion constructors are needed – single argument constructor that turn objects of other types (including built-in types) into objects of a particular (constructor’s) class. This constructor is called implicitly by the constructor.

• A constructor/cast operator converts an object of one class into an object of another class or into an object of a built-in type. //Assignment operator or overloaded role from CHHG

• This operator must be a non-static member function

• It cannot be a friend function

• It does not specify a return type – type to which an object is being converted

• Prototype for cast operator: CastFromClass::operator const

Page 17: C++ Operator Overloading

Converting between Types …• Prototype for cast operator: CastFromClass::operator

const

– E.g. A::operator char *() const; (char *)s=s.operator char*()

• When necessary, the compiler can call cast operators and conversion constructors to create temporary objects– E.g. for object ‘s’ of class string, cout << s is

converted by compiler to first (char *) as required by cout so for class string << need not be overloaded for cout

• For converting a basic type into user-defined type, one argument constructor is used.

• Complier blurs distinction between definition & assignment. If no overloaded operator available then compiler will look for the constructor to do the same job.

Distance d1 = 2.345; d1 = 1.0; Constructor is used but

no new object is created (through unnamed object)• For converting a user-defined type to basic, a

conversion function is required– Mtrs=float(dist2) and mtrs = dist2 will use same

conversion function

Page 18: C++ Operator Overloading

Converting between Types …• For converting from user-define to another user-defined

type then if conversion routine to be in source object, use conversion function else (conversion routine to be in destination object) use one-argument constructor.

• In second case, special functions (get functions) may be required to provide access to private data members of object to be converted

Avoid doing same conversion in more than one way i.e. single argument constructor is destination object & conversion function in source object.

Page 19: C++ Operator Overloading

Overloading ++ and --

• These operators have both prefix and postfix versions.

• So, each operator overloading function must have a distinct signature so the compiler will be able to determine which versions of ++/-- is intended

• Prefix versions are overloaded exactly as any other prefix unary operator would be.

• Postfix versions are overloaded in a manner to have different signature, achieved by making argument list for postfix version.

• Example declarations:Date d1;Pre-incrementingMember function: ++d1 = d1.operator(); Prototype Date operator ++()Non-member function:++d1 = operator(d1); Prototypefriend Date operator++(Date

&)Post-incrementingMember function: d1++ = d1.operator(0); Prototype Date operator ++(int)Non-member function:d1 ++= d1.operator(d1,0); Prototypefriend Date operator++

(Date &,int)

Page 20: C++ Operator Overloading

Overloading ++ and -- …

• Similar is the case for pre-and post decrementing

It is not an argument but a signal to compiler to use postfix notation.

c2 = c1++; c1 is first assigned to c2 and then incremented

Page 21: C++ Operator Overloading

Operators that cannot be overloaded

• Member access dot operator (.)• Scope resolution (::)• Conditional Operator (?:)• Pointer to member (.*)• sizeof()

Page 22: C++ Operator Overloading

Some uses of operator overlaoding

1. Add English distances: Add X1 to X2 & Y1 to Y2

2. Add Polar Co-ordinates: 3 step approach convert to English, Add, Convert back

3. String Concatenation: Check final string should not result in overflow

4. Distance & String comparison

5. Polar to rectangular conversion

Page 23: C++ Operator Overloading

More notes available at:

• http://www.cplusplus-naturally.blogspot.com

• http://zainvi.sf.googlepages.com/index.htm

• http://www.computer-science-notes.blogspot.com

Page 24: C++ Operator Overloading

Thank You

Questions?

Suggestions?