operator overloding. objectives operator overloading type conversion new style casts and rtti(run...

98
OPERATOR OVERLODING

Upload: ellen-warner

Post on 11-Jan-2016

220 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

OPERATOR OVERLODING

Page 2: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Objectives

• Operator Overloading• Type Conversion• New Style Casts and • RTTI(Run time type Information)

Page 3: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

• Overloading an operator means programming an operator to work on

operands of types it has not yet been designed to operate.

Overloading Operators—The Syntax:

• Operators are overloaded by writing operator-overloading functions.

• These functions are either member functions or friend functions of that

class whose objects are intended as operands of the overloaded operator.

• Operator overloading functions are very similar to the member functions

and friend functions. The only thing peculiar about them is their name.

• The names of operator-overloading functions are composed of the

keyword operator followed by the symbol of the operator being

overloaded.

• We can overload all the C++ operators except the following:

(i) class member access operator(., .*)

(ii) scope resolution operator (::)

(iii) size operator (sizeof) (iv) conditional operator(?:)

Page 4: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Operators—The Syntax:

• The syntax for member functions that overload a given operator is as follows:

• Member functions that overload operators can be private, protected, or public.

• The prototype of the operator-overloading function specifies a return type.

• The keyword operator follows the return type.

• This is followed by the symbol of the operator being overloaded.

• Finally, a pair of parentheses containing the formal arguments is specified.

Page 5: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Operators—The Syntax:

• The syntax for a friend function that overloads a given operator is as follows:

• Operator-overloading function can be defined and used as a member function. (See Example 1)

• Operator-overloading function can be defined as a friend function. (See Example 2).

Page 6: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Defining operator overloading using member function

Example1:

class <class name>

{

<return type> operator <op> (<argumentlist>); //prototype

};

<return type> <classname> ::operator <op> (<argumentlist>)//definition

{ //Function body

}

• Where return type is the type of value returned by the specified operation.

•operator op is the function name.

• Operator functions must be either member functions or friend functions.

Overloading Operators—The Syntax:

Page 7: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Defining operator overloading using friend function

Example2:

class <class name>

{

friend <return type> operator <op> (<argumentlist>); //prototype

};

return type operator <op> (<argumentlist>)//definition

{

//Function body

}

• Where return type is the type of value returned by the specified operation.

• operator op is the function name.

Overloading Operators—The Syntax:

Page 8: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Differences between member function and friend function w.r.to

operator overloading

•A basic difference between them is that a friend function will have only

one argument for unary operators and two for binary operators, while a

member function has no arguments for unary operators and only one for

binary operators.

•The friend function takes one argument more than member function

because the invoking object appears as an explicit parameter to the

friend function whereas in member functions it is passed as an implicit

parameter.

Page 9: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

The process of operator overloading involves the following steps:

1. Create a class that defines the data type to be used in the overloading.

2. Declare the operator function operator op() in the public part of the

class. It may be either a member function or a friend function.

3. Define the operator function to implement the required operations.

• Overloaded operator functions can be invoked by expressions such as:

op x or x op : for unary operator

x op y : for binary operators

Page 10: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading unary minus

// overloading unary minusclass space {

int x; int y; int z;

public :

void getdata(int a, int b, int c);

void display(void);

//friend void operator-(space &s); // declaration

void operator-();// using member function

};

Page 11: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

void space :: getdata(int a, int b, int c)

{

x=a;y=b;z=c;

}

void space ::display(void)

cout<<x;

cout<<y;

cout<<z;

}

void space:: operator-()

{

x=-x;

y=-y;

z=-z;

}

Page 12: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

int main()

{

space S;

S.getdata(10,-20,30);

cout<<"S:";

S.display();

-S;

cout<<"S";

S.display();

return 0;

}

output

10 -20 30

-10 20 -30

Page 13: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

To overload unary minus using friend function

friend void operator-(space &s); // declaration

void operator -(space &s) // definition

{

s.x=-s.x;

s.y=-s.y;

s.z=-s.z;

}

Page 14: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

overloading binary operators to add two complex numbers

c=sum(A,B) // functional notation

c=A+B // arithmetic notation

overloading + operator to add two complex numbers:

class complex

{

float x;//real part

float y;//imaginary part

public:

complex(){};// constructor 1

Page 15: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

complex (float real, float imag)

//constructor 2

{

x=real;y=imag;

}

complex operator+(complex);

void display(void);

};

Page 16: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

complex complex::operator+(complex c)

{

complex temp;

temp.x=x+c.x;

temp.y=y+c.y;

return(temp);

}

void complex::display(void)

{

cout<<x<<"+j"<<y<<"\n";

}

Page 17: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

int main()

{

complex C1,C2,C3;

C1=complex(2.5,3.5);

C2=complex(1.6,2.7);

C3=C1+C2;

cout<< "C1=";C1.display();

cout<<"C2=";C2.display();

cout<<"C3=";C3.display();

return 0;

}

Page 18: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

C1=2.5+i3.5;

C2=1.6+i2.7;

C3=4.1+i6.2;

The operator+() operates in the following way:

1. it receives only one complex argument explicitly

2. it returns a complex type value

3. it is a member function of complex

C3=C1+C2; // invokes operator+() function

• C1 takes the responsibility of invoking function.

• C2 is the argument object

The statement is equivalent to

C3=C1.operator+(C2);// usual function call

temp.x=x+c.x;

c.x refers to object C2 and x refers to object C1, since data

members of C1 are accessed directly.

Page 19: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

OVERLOADING BINARY OPERATOR USING FRIENDS

The complex number program can be modified as follows:

1.Replace the member function declaration by the friend function

declaration

friend complex operator+(complex, complex);

2.Redifine the operator function as follows

complex operator+(complex a, complex b)

{

complex temp;

temp.x=a.x+b.x;

temp.y=a.y+b.y;

return(temp);

}

Page 20: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

in this case the statement

C3=C1+C2 is equivalent to

C3=operator+(C1,C2);

Reason for using overloading using friend function:

Suppose A and B are the objects of the same class then,

A=B+2; // will work for the member function &friend function

A=2+B; //will not work for member function , but will work for

//friend function, since left-hand operand is responsible for

invoking the member function.

Page 21: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Compiler Interpretation of Operator-Overloading Functions• The compiler interprets operator-overloading functions is shown :

s3=s1+s2; // s1,s2 and s3 are objects of the class string

• If the operator overloading function has been declared as a member function, then the following interpretation is satisfied:

s3=s1.operator+(s2);

• If the operator overloading function has been declared as a friend function, then the following interpretation is satisfied:s3=operator+(s1, s2);

• However, we must note that the operator-overloading functions can be called directly from within the application programs :s3=s1.operator+(s2); s3=operator+(s1, s2);

• The benefit of overloading the operator will not be felt if the overloaded operators are directly called in this manner.

Page 22: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Manipulating string using operators

• There are no operators for manipulating the strings.

• In order to copy one string to another , the programmer must first

determine its length and allocate the required amount of memory.

• C++ allows us to create our own definitions of operators that can be

used to manipulate the strings very much similar to the decimal

numbers.• We can manipulate the strings using string class as follows:• For example , we shall able to use statements like:

string3 = string1 + string2

Page 23: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Example illustrating the applications of overloaded operators

#include <iostream.h>

#include <string.h>

class string

{

char *p;

int len;

public:

string () { len = 0; p=0; } //create null string

string (char *s)

{

len=strlen(s); p=new char[len+1];

strcpy(p,s);

}

Page 24: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

friend string operator + (string &s, string &t);friend string void show(string s);

};

string operator + (string &s , string &t){

string temp;temp.len=s.len+t.len;temp.p=new char[temp.len+1];strcpy(temp.p,s.p);strcat(temp.p,t.p);return (temp);

}

Page 25: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

void show (string s)

{

cout<<s.p<<endl;}

void main()

{

string s1 = "New"; // string s1(“New”);

string s2 = "Delhi";

string s3;

clrscr();

s3=s1+s2;

show(s1);

show(s2);

show(s3);

getch();

}

Page 26: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Operator overloading becomes mandatory under the following circumstances:

1. Objects of the class acquire resources dynamically during run time and no two objects should share the same copy of the resource.

Example:

string s1(“abc”), s2;

s2=s1;

2. Objects of the class acquire some resources dynamically during run time and no two objects should share even different copies of the resource.

Example:

s2=s1; // should not compile at all

The solution is to declare the function to overload the assignment operator in the private section of the class. This will produce an compile time error.

3. Objects need to be passed as parameters in function templates and the operators being used on template class objects within the template functions should work in the same way on objects of the class.

4. Change in the implementation of the class forces an undesirable change in its interface in turn necessitating the rewriting and recompiling of the application programs.

Page 27: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Operator overloading becomes mandatory under the following circumstances:

5. The default action of the dynamic memory management operators (new and delete) are unsuitable for the class being designed. • By default, the new operator allocates the amount of memory requested, and also stores the amount of memory allocated in the memory itself.• In memory critical applications, overloading the new operator can

prevent a huge wastage of memory.• By default, the new operator simply allocates memory for the object whose type is passed as an operand to it. To prevent the class from having more than one object, subsequent calls to the new operator should not create more objects, but merely return the address of the object that was created in response to the first call to the new operator.

6. Overloading provides better readability of code.

Page 28: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Rules for Operator Overloading

1. New operators cannot be created: New operators (such as **) cannot be created.

Example:

class A

{

public: void operator **(); //illegal attempt to create a new operator

};

2. Meaning of existing operators cannot be changed:

• Any operator-overloading function (member or friend) should take at least one operand of the class of which it is a member or friend. Thus, it is not possible to change the manner in which an existing operator works on operands of fundamental types (char, int, float, double).

Example:

class A

{ public: friend int operator + (int, int); //illegal attempt to modify the behavior of operators

};

• In case of member functions, this condition is automatically enforced because the address of the calling object is implicitly passed as a parameter to it.

• However, in case of friend functions, the library programmer needs to take extra care. By ensuring that at least one operand of an operator-overloading function must be of the class type, the compiler ensures that the meanings of the existing operators cannot be changed.

Page 29: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Rules for Operator Overloading

3.Some of the existing operators cannot be overloaded: The following operators cannot be overloaded:

:: (scope resolution)

. (member selection)

.* (member selection through pointer to member)

?: (conditional operator)

sizeof (finding the size of values and types)

typeid (finding the type of object pointed at)

4.Some operators can be overloaded using non-static member functions only:

= (Assignment operator)

() (Function operator)

[] (Subscripting operator)

-> (Pointer-to-member access operator)

These operators cannot be overloaded using friend or static functions

Page 30: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Rules for Operator Overloading5. Number of arguments that an existing operator takes cannot be changed: Operator

overloading functions should take the same number of parameters that the operator being overloaded ordinarily takes. For example, the division operator takes two arguments.

Example:

class A

{

public: void operator / (); //illegal attempt to modify the no. of arguments

};

6. Overloaded operators cannot take default arguments: An illegal attempt to assign a default value to an argument of an operator-overloading function causes a compile-time error.

Example:

class A

{

public: void operator / (int =0); //illegal attempt to assign a default value to opeartor overloaded function

};

Page 31: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Rules for Operator Overloading

7. It is highly imprudent to modify the values of the operands that are passed to the operator-overloading functions.

Example:

class string

{

char *cstr;

long int len;

public:

string operator + (string &);

};

string string :: operator + (string &ss)

{

this -> cstr=NULL; //BUG: left-hand parameter changed

// rest of the function

ss.cstr->=NULL ; //BUG

}

To guard against this mishap, the operator-overloading function can be declared.

Page 32: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Rules for Operator Overloading

To guard against this mishap, the operator-overloading function can be declared:

class string

{

char *cstr;

long int len;

public:

string operator + (const string &) const;

};

Page 33: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators1. Overloading increment and decrement operators (prefix and postfix):

The prototype and definition of the operator-overloading function for the

class Distance is shown in the example:

• The operator-overloading function should be public because it will mostly

be called from within functions that are not members of the class

Distance.

• It should not be a constant member function since it will certainly modify

the value of at least one of the data members of the calling object.

• First, the increment operator works (since it is in prefix notation).

• The explicit call to the constructor creates a nameless object of the class

distance by passing the incremented value of feet and the unaltered value

of inch as parameters.

• The operator-overloading function returns the nameless object thus

constructed.

Page 34: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various OperatorsExample: Overloading increment operator for distance class in prefix notation

class distance

{

int feet;

float inch;

public:

distance () { feet=inch=0;}

distance (int x, float y) { feet=x; inch=y;}

// rest of the class

distance operator ++();

};

distance distance:: operator ++ ()

{

return distance(++feet, inch);

}

• If d1 and d2 are the 2 objects of the class distance , then the statement:

d2=++d1;

Is interpreted by the compiler as:

d2=d1.operator++();

Page 35: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

• If the call to the operator-overloading function is on the right-hand side of the assignment operator, the values of the returned object will expectedly be copied to the object on the left.

• An additional operator-overloading function to overload the increment operator can be defined in postfix notation.

Example: Overloading increment operator for distance class in postfix notation

class distance

{ public:

// rest of the class

distance operator ++(int);

};

distance distance:: operator ++ (int)

{

return distance(feet++, inch);

}

Page 36: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators• The constructor gets called before the increment operator executes

because the increment operator has been purposefully placed in postfix

notation. Thus, a nameless object with the initial values of the calling object

is created.

• The increment operator increments the value of feet data member of the

calling object. Finally, the nameless object constructed earlier with the initial

values of the calling object is returned.

• If the call to this operator-overloading function is on the right-hand side of

the assignment operator and there is an object of the class distance on its

left, then the object on the left will get the initial values of the object on the

right. The value of the object on the right will alone be incremented.

• These two operator-overloading functions convincingly duplicate the default

action of the increment operator on intrinsic types.

Page 37: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators• If we provide an operator-overloading function for the increment operator in

prefix notation, we must provide one for the postfix notation also.

• Decrement operators are overloaded in the same way as the increment

operators.

• If d1 and d2 are the 2 objects of the class distance , then the statement:

d2=d1++;

Is interpreted by the compiler as:

d2=d1.operator++ (0); //integer 0

•If the compiler finds a exact matching prototype for postfix form, it

compiles without warning errors.

•However, if it finds prototype for prefix form only it gives warning but

still compiles with distance::operator+(). i.e., the compiler first looks

for a function with an integer as a formal parameter.

Page 38: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

Overloading unary minus and unary plus operator:

The unary minus operator can be overloaded through a member function. (The

operator can be overloaded by a friend function also.)

Example:

class A

{ int x;

public: A(int=0);

A operator –(); // or friend A operator –( A &)

};

A A::operator-() // A operator – (A &Aobj)

{ return A(-x); // or return A (-Aobj.x) ;

}

Page 39: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

Overloading arithmetic operators:

1.The syntax for overloading the arithmetic operators through member

functions is as shown:

<return type> operator <arithmetic symbol> (<parameter list>);

•An object that will store the value of the right-hand side operand of the

arithmetic operator will appear in the list of formal arguments.

•The left-hand side operand will be passed implicitly to the function since the

operator-overloading function will be called with respect to it.

2. The syntax for overloading the arithmetic operators through friend functions

is as shown:

friend <return type> operator <arithmetic symbol> (<parameter list>);

•Objects that store the values of the left-hand side and the right-hand side

operands of the arithmetic operator will appear in the list of formal arguments.

Page 40: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

Overloading arithmetic operators:• How to overload the addition operator for the class Distance is as shown :

distance d1(7,8), d2(4,9),d3;

d3=d1+d2;

•This can also be done through either by member function or by friend function. •This code works fine if the right-hand side operand of the addition operator is an object of class Distance.•However, if it is a float-type value, then the preceding function will not work.

Example:

d3=d1+9.5; //will not work

Because, the compiler will interpret this statement as:

d3= d1.operator+(9.5);

Page 41: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

Overloading arithmetic operators:

•However, introducing a suitable constructor that converts from float to Distance

solves the problem.

class distance

{ public:

distance (float );

distance operator +(distance);

};

distance:: distance( float p)

{

feet= (int) p;

inch=(p-feet)*12;

}

•However, if the left-hand side operand is of float type, the member function given in Listing 8.20 is replaced with a friend function. (See Listing 8.22).

Page 42: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

Overloading arithmetic operators: •However, if the left-hand side operand is of float type, for example:

d3=9.5+d1; //will not work for member function

Because, the compiler will interpret this statement as:

d3= 9.5.operator+(d1);//illegal

•the member function given in previous example is replaced with a friend function.

class distance

{ public:

distance (float );

friend distance operator +(distance, distance);

};

distance:: distance( float p)

{

feet= (int) p;

inch=(p-feet)*12;

}

Page 43: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

• The friend function given in previous example tackles all three conditions as follows:

1. Both the left-hand side and the right-hand side operands are objects of class Distance: The operator-overloading function is called straight away without any prior conversions.

2. The right-hand side operand is a float-type value while the left-hand side operand is an object of class Distance: The right-hand side operand is first converted into an object of the class Distance by the constructor and then the operator-overloading function is called.

3. The left-hand side operand is a float-type value while the right-hand side operand is an object of class Distance: The left-hand side operand is first converted into an object of the class Distance by the constructor and then the operator-overloading function is called.

Page 44: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

• Where both operands are float-type values, the operator-overloading

mechanism will not be invoked at all. Instead, the float-type values will

simply get added to each other.

• For the class Distance, there is no function that converts a float-type value

to an object of class Distance. The constructor that takes a float-type value

as a parameter and initializes the object with it will be called. This is

despite the fact that the object is being created and initialized by two

separate statements. Such a constructor is called an implicit constructor.

• Having both a friend function and a member function will lead to ambiguity

errors.

Page 45: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

Overloading assignment operator:

• The assignment operator is a binary operator. If overloaded, it must be overloaded by a non-static member function only. Thus, the syntax for overloading the assignment operator is as shown :

class_name & operator = (class_name &);

• By default, the compiler generates the function to overload the assignment operator if the class designer does not provide one. This default function carries out a simple member-wise copy. For example:

Example:

class A

{

public:

&A operator = (A&);

};

A & A::operator =(A & rhs)

{ *this=rhs;

return *this;

}

In most cases, this default assignment operator is sufficient. However, there are cases where this default behaviour causes problems if the copy constructor is not defined. (See Listing 8.30). Pg 236 further explanation required

Page 46: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

• In most cases, the default assignment operator is sufficient. For classes that acquire resources dynamically, default causes problem.

• String s1(“abcd”); String s2= s1; • The conclusion is that the assignment operator must

be defined for a class whom the copy constructor is defined. Example

String (const String &); // copy constructor

String & operator = (const String &);

String String :: operator = (const String & ss)

{ if this != &ss)

{if(cStr != NULL) {delete[] cStr; cStr = NULL;len=0; }

Page 47: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

Overloading assignment operator:

String & string ::operator =(string & ss)

{ if (this!=&ss)

{

if (cstr!=NULL)

{ delete [] cstr;

cstr=NULL;

len=0;

}

if (ss.cstr!=NULL)

{ len=ss.len;

cstr=new char[len+1];

strcpy(cstr,ss.cstr);

}

} return *this;

}

Page 48: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

(i)If LHS.cStr =NULL and RHS.cStr =NULL

• If LHS.cStr =NULL, then the first inner ‘if’ fails and the corresponding if block does not execute. If RHS.cStr =NULL then the second inner ‘if’ fails and the block does not execute.

• The entire function does not do anything except that it returns the calling object by reference. The value of LHS operand remains unchanged.

Page 49: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

• (ii)If LHS.cStr =NULL and RHS.cStr !=NULL

If LHS.cStr =NULL, then the first inner ‘if’ fails and the corresponding if block does not execute.

If RHS.cStr =!NULL then the second inner ‘if’ (if(ss.cStr!=0)) succeeds and the corresponding ‘if’block executes. It does the following: (i) correctly sets the value of len member of the calling object to be equal to the length of the memory block that will hold a copy of the string at which ‘cStr’ member of the RHS object is pointing. (ii) allocates just enough memory to hold a copy of the string at which the cStr member of the RHS object is pointing and makes cStr of LHS object point at it

• Copies the string at which the cStr of RHS object is pointing in to the memory block at which the cStr of LHS object is pointing.

Page 50: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

(iii) If LHS.cStr !=NULL and RHS.cStr =NULL then the first inner ‘if’ succeeds and the corresponding if block executes.

• It deallocates the memory the block at which cStr of LHS object points, sets its value to NULL and sets the value of the ‘len’ member of LHS object to ‘0’. If RHS.cStr=NULL then the second inner ‘if’ fails and the corresponding if block does not execute.

• If LHS.cStr !=NULL and RHS.cStr !=NULL then the first inner block succeeds and executes.

Page 51: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

It deallocates the memory the block at which cStr of LHS object points, sets its value to NULL and sets the value of the ‘len’ member of LHS object to ‘0’. If RHS.cStr!=NULL then the second inner ‘if’ succeeds and the corresponding if block executes. It does the required things.

• The preceding function accepts the argument as a const reference and returns the calling object by reference – to test and safeguard against self-assignment. The if condition ‘this == &ss’ tests to find out whether an object is being equated with itself or not.

Page 52: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

• An object may be get equated as

String s1 ; s1 = s1; or

String s1; String &s2 = s1; s2 = s1;• Each of the above will cause an extension of the

function to overload the assignment operator. In each of the cases ‘if’ evaluates to true. For such circumstances the operator overloading function has been designed to remain unexecuted. This is necessary because in case of self assignment no action is necessary. Unnecessary allocation-deallocation should be avoided.

• The function has been designed to return by reference – to prevent chaining operation from

Page 53: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

being inefficient, that is, to ensure an efficient execution of statements such as :

String s1, s2, s3; s3= s2 = s1; interpreted as

s3.operator = (s2.operator = (s1) );

suppose s2= s2 = s1; suppose it is returned by value and not by reference. Then value of s2 is created in stack and its address is different from that of s2. When the assignment operator executes for the second time, reference variable ‘ss’ refers to this copy and not to s2 itself.

• When the library programmer wants to overload the ‘assignment’ operator and may not want to share even different copies of the same object.

Page 54: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

• A derived class object can be assigned to a base class object but the reverse is not true.

• A A1 ; B B1; A1=B1; //OK B1= A1; //ERROR!

• the data members exclusively in B1 will remain unchanged and may no longer match with rest of the members of ‘B1’. Hence the compiler prevents!

• If the class designer desires, he may provide an assignment operator function to the derived class. public: B& operator = (const A&); //to enable B1=A1

Page 55: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

Overloading assignment operator:

• In most cases, this default assignment operator is sufficient. However, there are cases where this default behaviour causes problems if the copy constructor is not defined.

Example:

class string

{ char *cstr;

int len;

public:

string () { len = 0; p=0; } //create null string

string & operator = (string &);

};

String & string ::operator +(string & ss)

{

if (this!=&ss)

Page 56: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various OperatorsOverloading relational operators

• Relational operators are binary operators.

1. The syntax for overloading them through member functions is given below:

<return type> operator <relational symbol> (<parameter list>);

• An object that will store the value of the right-hand side operand of the relational operator will appear in the list of formal arguments. The left-hand side operand will be passed implicitly to the function since the operator-overloading function will be called with respect to it. The expression:

obj1 <relational symbol> obj2

will be interpreted as:

obj1.operator <relational symbol> (obj2)

2. The syntax for overloading relational operator using friend function is as follows:

friend <return type> operator <relational symbol> (<parameter list>);

• Objects that store the values of both the left-hand side and the right-hand side operands of the relational operator will appear in the list of formal arguments.

Page 57: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various OperatorsOverloading relational operators

• Suppose d1,d2 are the objects of the class distance then the following code must be compiled successfully :

if (d1>d2)

cout<<“greater than “

else

cout<<“less than”;

• For this, we must overload the ‘>’ operator for the distance class .

• The expression:

d1>d2

Will be interpreted as

d1.operator > (d2)

Page 58: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

Overloading relational operators

• How to overload the greater than relational operator for the class Distance is shown in Listing.

Example:

enum bool {false, true};

class distance

{ public:

// rest of the distance

bool operator > (distance); //member function

};

bool distance:: operator > ( distance d)

{ if (feet*12+inch> d.feet*12+d.inch)

return true;

else return false;

}

Page 59: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

Overloading relational operators

• The code mentioned in the previous example works fine if the right hand side operand is an object. However, if it is a float type value, for example, the expression .

d1>6.5; //will not compile

• The compiler will interpret this expression as:

d1.operator > (6.5);

• In order make the above expression to work, a suitable constructor which converts float to distance is must be defined under distance class.

• However, if the left-hand side operand is of float type, for example:

9.5>d1; //will not work for member function

• To solve this problem, the member function given in previous example is replaced with a friend function.

• Therefore , upon using the friend function, all the 3 conditions can be tackled.

• If both the definitions, i.e., member as well as friend function is present in a class definition for overloading relational operator, the compiler will be confused . This will lead to an ambiguity error.

Page 60: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Stream-Insertion and Stream-Extraction Operators

• Overloaded << and >> operators– Overloaded to perform input/output for user-defined types– To be consistent with the IO library , the operator should take

ostream& or istream& as its first parameter and a reference to a const object of the class type as its second parameter

– Left operand of types ostream & and istream &– Must be a non-member function because left operand is not an object

of the classFor example:

cin>>A1; // A1 is an object of class AIs interpreted as:

operator >>(cin,A1);

– Must be a friend function to access private data members

Page 61: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Stream-Insertion and Stream-Extraction Operators

• The syntax for overloading the insertion operator is shown:

class A

{

public: friend ostream & operator << (ostream &, A&);

// rest of class A

};• The syntax for overloading the extraction operator is shown:

class A

{

public: friend istream & operator >> (istream &, A&);

// rest of class A

};

Page 62: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Stream-Insertion and Stream-Extraction Operators

• The objects of the classes istream and ostream are passed and returned by reference in the preceding functions.

• The copy constructor and the assignment operator have been declared as protected members in both the classes istream and ostream. This prevents two objects from undesirably sharing even different copies of the same stream.

• For example following statements will throw compile time errors :

ostream out=cout; //ERROR

istream in = cin; //ERROR

• There is a compulsion to return by reference. If the object is returned by value, then a separate object is created in the stack. A call to the copy constructor is dispatched with respect to it and the object returned by the operator-overloading function is passed as a parameter. However, the copy constructor is a protected member. Therefore, the object must be returned by reference and not by value.

Page 63: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Example Program:Overloaded << and >> operators class PhoneNumber {private:char areaCode[ 4 ]; // 3-digit area code and nullchar exchange[ 4 ]; // 3-digit exchange and nullchar line[ 5 ]; // 4-digit line and null

public:friend ostream &operator<<( ostream&, const PhoneNumber & ); friend istream &operator>>( istream&, PhoneNumber & );};

ostream &operator<<( ostream &output, const PhoneNumber &num ){output << "(" << num.areaCode << ") "<< num.exchange << "-" << num.line;return output; // enables cout << a << b << c;}

Page 64: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloaded << and >> operators

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

input >> num.areaCode; // input area codeinput >>num.exchange; // input exchangeinput>>num.line; // input linereturn input; // enables cin >> a >> b >> c;

}

void main(){

PhoneNumber phone; // create object phonecout << "Enter phone number \n";cin >> phone;cout << "The phone number entered was: " << phone << endl;}

Page 65: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Program Output

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

Page 66: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

Overloading subscript operator:

• The subscript operator [] is normally used to access array elements. This operator can be overloaded to enhance the existing functionality of C++ arrays.

• Thus, the syntax for overloading the subscript operator is as shown :

class <class name>

{

public:

<return type> operator [] (<parameter list>);

};

Page 67: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Example: Overloading [] operator

const int SIZE=10;

class array

{

private:

int arr[SIZE];

public:

array()

{

int i;

for(i = 0; i < SIZE; i++)

{ arr[i] = i; }

}

int &operator[](int i)

{

if( i > SIZE )

{ cout << "Index out of bounds" <<endl;

// return first element.

return arr[0]; }

return arr[i];

}

Page 68: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

int main()

{

array A;

cout << "Value of A[2] : " << A[2] <<endl;

cout << "Value of A[5] : " << A[5]<<endl;

cout << "Value of A[12] : " << A[12]<<endl;

return 0;

}

When the above code is compiled and executed, it produces the following result:

Value of A[2] : 2

Value of A[5] : 5

Index out of bounds

Value of A[12] : 0

Page 69: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

Overloading subscript operator:

• The subscript operator [] is normally used to access array elements. This operator can be overloaded to enhance the existing functionality of C++ arrays.

• Thus, the syntax for overloading the subscript operator is as shown :

class <class name>

{

public:

<return type> operator [] (<parameter list>);

};

<return_type> <class_name> operator[] <param_list>

{// statements }

Page 70: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

class String

{ public:

char& operator[] (const int) ;// for non-const objects

char& operator[] (const int) const;//for const objects };

char& String ::operator[] (const int p)

{ return cStr[p] ;}

char& String ::operator[] (const int p) const

{ return cStr[p] ;}• The function returns the corresponding element by

reference. Because the subscript operator might be used on LHS of assignment operator also.

Page 71: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

s[1] = ‘x’ ; // assign ‘x’ to second char of s

• If you use the first function for the constant object like const String s(“abcd”); cout <<s[1];//ERROR . Hence we introduced a second function.

• Also s[1] = ‘x’; //compiles• To prevent this we should make the return type

reference.• The formal argument of the function that overloads the

‘subscript’ operator can be of any type such as int, char, float, double.

Page 72: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading Various Operators

Overloading assignment operator:

• The subscript operator [] is normally used to access array elements. This operator can be overloaded to enhance the existing functionality of C++ arrays.

• Thus, the syntax for overloading the subscript operator is as shown :

class <class name>

{

public:

<return type> operator [] (<parameter list>);

};

Page 73: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading ‘new’ and ‘delete’ operators

•The ‘new’ and ‘delete’ operators are usually sufficient for most programs

but there might be cases wherein you want to overload them as well.

Some important points are:

• You can overload these operators globally or you can overload them

for specific classes. If you overload using member function for a class then

we say that you have overloaded only for that specific class.

•If overloading is done outside a class (i.e. it is not a member function of a

class), the overloaded ‘new’ and ‘delete’ will be called anytime you make

use of these operators (within classes or outside classes). This is global

overloading.

• Be careful if you overload ‘new’ and ‘delete’ globally (because there

might be other parts of your program which rely on the normal operation of

these operators).

•Usually programmers do not overload them globally.

Page 74: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Overloading ‘new’ and ‘delete’ operators

The default action of the dynamic memory management operators (new

and delete) are unsuitable for the class being designed.

•By default, the new operator allocates the amount of memory

requested, and also stores the amount of memory allocated in the

memory itself.

• In memory critical applications, overloading the new operator can

prevent a huge wastage of memory.

• By default, the new operator simply allocates memory for the object

whose type is passed as an operand to it. To prevent the class from

having more than one object, subsequent calls to the new operator

should not create more objects, but merely return the address of the

object that was created in response to the first call to the new

operator.

•Overloading provides better readability of code.

Page 75: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

The syntax for overloading ‘new’ and ‘delete’ are:

void* operator new (size_t n){    //allocate memory and return the address (a void pointer)}void operator delete (void *p){    //free the memory space pointer to by the pointer ‘p’}You will notice that the parameter for ‘new’ is:size_t n;•size_t is a numerical data type defined by the system to specify memory size in bytes. Type size_t is an implementation dependent unsigned integral type defined in <stddef.h>. For instance if you use ‘new’ to create a character, the value of n (i.e. the argument passed to ‘n’) will be 1. If you pass a ‘double’ quantity then the value of ‘n’ will be 8 (you needn’t worry about this).•The ‘new’ operator should return a void pointer while the ‘delete’ operator will pass a void pointer as argument.

Overloading ‘new’ and ‘delete’ operators

Page 76: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

New and Delete operators• The behavior of these operators can be altered for operands of

specific class types. If the operators are overloaded for specific class, then the functions that overload are called when the class type is passed as a parameter to these operators. Otherwise the global new and delete operators are called.

• If ‘new’ is overloaded in class ‘X’ and not in ‘Y’ , then • X* Xptr = new X; //overloaded new where as • Y * Yptr = new Y; // global new

void * operator new(size_t); //prototype

void *<class_name> :: operator new(size_t size)

{ //definition of function }

Page 77: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

void * operator new[](size_t); //prototype

void *<class_name> :: operator new[](size_t size)

{ //definition of function – for array }

static void operator delete(void*, size_t); //prototype for delete

void <class_name> :: operator delete(void * p, size_t size)

{ //definition of function }

static void operator delete[](void*, size_t); //prototype for delete

void <class_name> :: operator delete[](void * p, { //definition of function } size_t size)

Page 78: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

• The new and delete functions must be static. Their prototypes need not be prefixed with ‘static’. The compiler treats these as ‘static’.

• The return type of the ‘new’ must be ‘void *’. The returned value is the address of the memory block. It should take at least on formal argument ‘size_t’.

class A

{ int x; public :

void * operator new(size_t); } ;

#include”A.h”

void * A :: operator new(size_t size)

{ cout<< sizeof(A)<<endl;

cout<<size <<endl;

void *p = ::operator new(size);

return p; }

Page 79: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

#include “A.h”

void main()

{ A * Aptr = new A; } // output 4 4

• Class designer will insert necessary code to overload ‘new’

operator and to allocate required amount of memory and then

to return the address of the captured memory.

• The type ‘size_t’(essentially an unsigned integer) is a defined

type capable of containing the largest piece of memory that can

be allocated. ‘size’ will contain the number of bytes needed to

hold the object being allocated.

Page 80: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

• The return type in ‘delete’ must be void, as it does not return anything. Its first argument should be of type void*. The address of the memory being deleted is passed to it. The second argument is ‘size_t’.

class A

{ int x; public : void operator delete (void * const, const size_t); } ;

#include”A.h”

void A :: operator delete (void * const p, const size_t size)

{ cout<< p<< endl ;

cout<< sizeof(A)<<endl;

cout<<size <<endl;

::operator delete(size); }

Page 81: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

#include “A.h”

void main()

{ A * Aptr = new A; cout<<Aptr<<endl; delete Aptr;}

output :OxCCCCCC OxCCCCCC 4 4

• ‘new’ and ‘delete’ functions are static by default. The compiler

places a call to constructor (destructor) immediately

after(before) the call to ‘new’ (‘delete’) operator.

A * Aptr = new A ; is translated as

A* Aptr =A :: operator new(sizeof(A));

A :: A(Aptr) ;// nameless object created and constructor called

for that object.

Page 82: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

• The statement delete Aptr; is translated as

A:: ~A(Aptr); //destructor called for nameless object

A:: operator delete (Aptr, sizeof (A) ); //nameless object

destroyed

Page 83: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

The program below overloads the ‘new’ and ‘delete’ operators globally. void* operator new(size_t n) {cout<<endl<<"overloaded new"; void *ptr; ptr = ::operator new(n); return ptr;} void operator delete(void *p) {cout<<endl<<"overloaded delete"; ::operator delete p ;} int main( ) {int *p = new int; *p=20; cout<<"\n The value is : "<<*p; //value of 20 delete p; cout<<"\n The value after deleting is : "<<*p; //some invalid value return 0;}The output will be: overloaded new The value is : 20 overloaded delete The value after deleting is : 4325404

Page 84: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

The C++ standard library comes with a set of predefined new and delete operators. The most important ones are these:

void* operator new(size_t) ; void operator delete(void*); void* operator new[](size_t) ; void operator delete[](void*);

•The first two allocate/deallocate memory for an object, the latter two for an

array of objects. If you overload operator new, you should always also

overload the matching operator delete, even if you never intend to call it.

The reason is that, if a constructor throws during the evaluation of a new

expression, the run-time system will return the memory to the operator delete

matching the operator new that was called to allocate the memory to create

the object in.

If you do not provide a matching operator delete, the default one is called,

which is almost always wrong. If you overload new and delete, you should

consider overloading the array variants, too.

Page 85: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

• What are smart pointers? Actually, smart pointers are objects which behave like pointers but do

more than a pointer. These objects are flexible as pointers and have the advantage of being

an object (like constructor and destructors called automatically). A smart pointer is designed to handle the problems caused by using

normal pointers (hence called smart).

• What are the common problems we face in C++ programs while using pointers?

In case of ordinary pointers, there is no guarantee that the pointer being used is pointing at valid block of memory.

Memory management. Consider following code:

Overloading pointer-to-member(->) operator (Smart pointer)

char* pName = new char[1024]; … SetName(pName); … … if(null != pName) { delete[] pName; }

Page 86: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

How many times have we found a bug which was caused because we

forgot to delete pName.

It would be great if someone could take care of releasing the memory

when the pointer is not useful .

What if the pointer itself takes care of that? Yes, that’s exactly what

smart pointers are intended to do. Let us write a smart pointer and see

how we can handle a pointer better.

Overloading pointer-to-member(->) operator (Smart pointer)

Page 87: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

class Person{ int age; char* pName;

public: Person(): pName(0),age(0) { } Person(char* pName, int age): pName(pName), age(age) { } ~Person() { }

void Display() { printf("Name = %s Age = %d \n", pName, age); }};

Overloading pointer-to-member(->) operator (Smart pointer)

Page 88: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

void main(){ Person* pPerson = new Person("Scott", 25); pPerson->Display(); delete pPerson;}

• Now we shall write the client code to use Person.

• Now look at this code, every time we create a pointer, we need to take care of deleting it. This is exactly what we want to avoid. We need some automatic mechanism which deletes the pointer. One thing which strikes to us is a destructor. But pointers do not have destructors, so what? Our smart pointer can have one. So we will create a class called SP which can hold a pointer to the Person class and will delete the pointer when its destructor is called. Hence our client code will change to something like this:

void main(){ SP p(new Person("Scott", 25)); p->Display(); // Dont need to delete Person pointer..}

Page 89: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Note the following things:

We have created an object of class SP which holds our Person class

pointer. Since the destructor of the SP class will be called when this

object goes out of scope, it will delete the Person class pointer (as its

main responsibility); hence we don’t have the problem of deleting the

pointer.

One more thing of major importance is that we should be able to call the

Display method using the SP class object the way we used to call using

the Person class pointer, i.e., the class should behave exactly like a

pointer.

Page 90: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Smart pointer implementation

class SP{private: Person* pData; // pointer to person classpublic: SP(Person* pValue) : pData(pValue) { } ~SP() { // pointer no longer requried delete pData; }

Person& operator* () { return *pData; }

Person* operator-> () { return pData; }};

Page 91: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Note the following things:

The main responsibility of smart pointer class is to hold a pointer to the

Person class and then delete it when its destructor is called. It should

also support the interface of the pointer.

Page 92: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Type Conversion – Class to Basic

The constructor handles the task of converting basic types to class types

very well. But you cannot use constructors for converting class types to

basic data types. Instead, you can define an overloaded casting

operator(type conversion operator) that can be used to convert a class

data type into a basic data type. The general form of an overloaded

casting operator function is shown below. This function is also known as

a conversion function.

The casting operator function should satisfy the following conditions:

•It must be a class member.

•It must not specify a return type.

•It must not have any arguments. The object that invokes this function

has its members directly accessible since this is a member function.

Page 93: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Type Conversion – Class to Basic

class DistConv{private: int kilometers; double meters; nbsp; const static double kilometersPerMile;public: // This function converts a built-in type (i.e. miles) to the // user-defined type (i.e. DistConv) DistConv(double mile) // Constructor with one // argument { double km = kilometersPerMile * mile ; // converts miles to //kilometers kilometers = int(km); // converts float km to //int and assigns to kilometer meters = (km - kilometers) * 1000 ; // converts to meters } DistConv(int k, float m) // constructor with two // arguments { kilometers = k ; meters = m ; } // ********Conversion Function************ operator double() // converts user-defined type i.e. // DistConv to a basic-type { // (double) i.e. meters double K = meters/1000 ; // Converts the meters to &nsp; // kilometers K += double(kilometers) ; // Adds the kilometers return K / kilometersPerMile ; // Converts to miles } void display(void) { cout << kilometers << " kilometers and " << meters << " meters" ; }}; // End of the Class Definitionconst double DistConv::kilometersPerMile = 1.609344;int main(void){ DistConv d1 = 5.0 ; // Uses the constructor with one argument DistConv d2( 2, 25.5 ); // Uses the constructor with two arguments double ml = double(d2) ; // This form uses the conversion function // and converts DistConv to miles cout << "2.255 kilometers = " << ml << " milesn" ; ml = d1 ; // This form also uses conversion function // and converts DistConv to miles d1.display(); cout << " = " << ml << " milesn" ;}

Output

2.255 kilometers = 1.25859 miles8 kilometers and 46.72 meters = 5 miles

Page 94: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Type Conversion – Class to Class

Now that we have understood how to convert basic data types to class

types and vice-versa, it is time to learn how to convert objects of one

class type to another class type.

The conversion between objects of different classes can be done using

either a one-argument constructor or a conversion function. The choice

depends upon whether the conversion routine has to be declared in the

source class or in the destination class. To illustrate, consider a program

that contains two classes: A and B. Also consider the statement:

object_A = object_B;

In the above statement, object_B of type B is converted to type A and

assigned to object_A. Therefore, object_B is the source and object_A is

the destination.

Page 95: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Type Conversion – Class to Class

For the conversion, the user can use either a conversion function or a

constructor with one argument, depending on whether it is specified in the

source class or the destination class.

In other words, if class B handles the conversion, it will hold a conversion

function. On the other hand, if class A carries out the conversion, it will do

that through a constructor that takes an argument of type class B.

Note that only one of the two conversion routines should be specified; the

compiler will yield an error if both are specified since it will not be able to

figure out which routine to call.

Page 96: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Type Conversion – Class to Class

class Kilometers{private: double kilometers;public: Kilometers(double kilometers): kilometers(kilometers) {} void display() { cout << kilometers << " kilometeres"; } double getValue() { return kilometers; }};

Page 97: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Type Conversion – Class to Class

class Miles{private: double miles;public: Miles(double miles) : miles(miles) {} void display() { cout << miles << " miles"; } operator Kilometers() { return Kilometers(miles*1.609344); } Miles(Kilometers kilometers) { miles = kilometers.getValue()/1.609344; }};

Page 98: OPERATOR OVERLODING. Objectives Operator Overloading Type Conversion New Style Casts and RTTI(Run time type Information)

Type Conversion – Class to Class

int main(void){ /* * Converting using the conversion function */ Miles m1 = 100; Kilometers k1 = m1; m1.display(); cout << " = "; k1.display(); cout << endl; /* * Converting using the constructor */ Kilometers k2 = 100; Miles m2 = k2; // same as: Miles m2 = Miles(k2); k2.display(); cout << " = "; m2.display(); cout << endl;}

Output100 miles = 160.934 kilometeres100 kilometeres = 62.1371 miles