OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

Slides:



Advertisements
Similar presentations
Pointers Typedef Pointer Arithmetic Pointers and Arrays.
Advertisements

A RRAYS, P OINTERS AND R EFERENCES 1. A RRAYS OF O BJECTS Arrays of objects of class can be declared just like other variables. class A{ … }; A ob[4];
Chapter 14: Overloading and Templates C++ Programming: Program Design Including Data Structures, Fifth Edition.
6/10/2015C++ for Java Programmers1 Pointers and References Timothy Budd.
Rossella Lau Lecture 10, DCO10105, Semester B, DCO10105 Object-Oriented Programming and Design  Lecture 10: Operator overload  Operator overload.
 2006 Pearson Education, Inc. All rights reserved Operator Overloading.
Chapter 14: Overloading and Templates
Operator Overloading in C++ Systems Programming. Systems Programming: Operator Overloading 22   Fundamentals of Operator Overloading   Restrictions.
Chapter 15: Operator Overloading
Shallow Versus Deep Copy and Pointers Shallow copy: when two or more pointers of the same types point to the same memory – They point to the same data.
Operator OverloadingCS-2303, C-Term Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The C Programming Language,
Operator Overloading in C++
Review of C++ Programming Part II Sheng-Fang Huang.
C++ Programming: Program Design Including Data Structures, Fourth Edition Chapter 14: Overloading and Templates.
Chapter 18 - Operator Overloading Associate Prof. Yuh-Shyan Chen Dept. of Computer Science and Information Engineering National Chung-Cheng University.
More About Classes Chapter Instance And Static Members instance variable: a member variable in a class. Each object has its own copy. static variable:
Operator Overloading and Type Conversions
Chapter 13: Pointers, Classes, Virtual Functions, and Abstract Classes
OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.
 2006 Pearson Education, Inc. All rights reserved Classes: A Deeper Look.
1 CISC181 Introduction to Computer Science Dr. McCoy Lecture 19 Clicker Questions November 3, 2009.
C++ Programming: Program Design Including Data Structures, Fourth Edition Chapter 13: Pointers, Classes, Virtual Functions, and Abstract Classes.
C++ Programming: From Problem Analysis to Program Design, Fourth Edition Chapter 15: Overloading and Templates.
Pointer Data Type and Pointer Variables
Data Structures Using C++ 2E Chapter 3 Pointers and Array-Based Lists.
C++ Programming: From Problem Analysis to Program Design, Fourth Edition Chapter 14: Pointers, Classes, Virtual Functions, and Abstract Classes.
Chapter 8 Friends and Overloaded Operators. Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 2 Overview Friend Function (8.1) Overloading.
More C++ Classes Systems Programming. C++ Classes  Preprocessor Wrapper  Time Class Case Study –Two versions (old and new)  Class Scope and Assessing.
CS212: Object Oriented Analysis and Design Lecture 6: Friends, Constructor and destructors.
CS212: Object Oriented Analysis and Design Lecture 12: Operator Overloading-II.
 2006 Pearson Education, Inc. All rights reserved Classes: A Deeper Look, Part 2.
Overloading Binary Operators Two ways to overload –As a member function of a class –As a friend function As member functions –General syntax Data Structures.
CS212: Object Oriented Analysis and Design Lecture 10: Copy constructor.
Hello.java Program Output 1 public class Hello { 2 public static void main( String [] args ) 3 { 4 System.out.println( “Hello!" ); 5 } // end method main.
C++ Programming: From Problem Analysis to Program Design, Second Edition1 Objectives In this chapter you will: Learn about the pointer data type and pointer.
Operatorsand Operators Overloading. Introduction C++ allows operators to be overloaded specifically for a user-defined class. Operator overloading offers.
 2006 Pearson Education, Inc. All rights reserved Operator Overloading; String and Array Objects.
CS212: Object Oriented Analysis and Design Lecture 7: Arrays, Pointers and Dynamic Memory Allocation.
Data Structures Using C++ 2E Chapter 3 Pointers. Data Structures Using C++ 2E2 Objectives Learn about the pointer data type and pointer variables Explore.
Chapter 12: Pointers, Classes, Virtual Functions, and Abstract Classes.
Overloading Operator MySting Example. Operator Overloading 1+2 Matrix M 1 + M 2 Using traditional operators with user-defined objects More convenient.
OPERATOR OVERLOADING Understand Operator Overloading and how it is implemented in C++ ? | Website for students | VTU NOTES.
 2008 Pearson Education, Inc. All rights reserved Operator Overloading.
Copyright 2005, The Ohio State University 1 Pointers, Dynamic Data, and Reference Types Review on Pointers Reference Variables Dynamic Memory Allocation.
©Fraser Hutchinson & Cliff Green C++ Certificate Program C++ Intermediate Operator Overloading.
C++ Programming: From Problem Analysis to Program Design, Third Edition Chapter 15: Overloading and Templates.
Copyright © 2009 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Chapter 14: More About Classes.
Chapter 13: Overloading and Templates. Objectives In this chapter, you will – Learn about overloading – Become familiar with the restrictions on operator.
Learning Objectives Fundamentals of Operator Overloading. Restrictions of Operator Overloading. Global and member Operator. Overloading Stream-Insertion.
1 Chapter 15-1 Pointers, Dynamic Data, and Reference Types Dale/Weems.
Chapter 12: Pointers, Classes, Virtual Functions, Abstract Classes, and Lists.
You learned how to declare pointer variables how to store the address of a variable into a pointer variable of the same type as the variable how to manipulate.
Operator Overloading.
CSE1002 – Problem Solving with Object Oriented Programming
Yan Shi CS/SE 2630 Lecture Notes
Constructors and Destructors
Overloading Operator MySting Example
Chapter 13: Pointers, Classes, Virtual Functions, and Abstract Classes
Chapter 15: Overloading and Templates
OPERATOR OVERLOADING.
Chapter 12: Pointers, Classes, Virtual Functions, and Abstract Classes
Chapter 14: Pointers, Classes, Virtual Functions, and Abstract Classes
Operator Overloading; String and Array Objects
Operator Overloading; String and Array Objects
Constructors and Destructors
Constructors and Destructors
Operator Overloading Professor Hugh C. Lauer CS-2303, System Programming Concepts (Slides include materials from The C Programming Language, 2nd edition,
9-10 Classes: A Deeper Look.
Operator Overloading; String and Array Objects
9-10 Classes: A Deeper Look.
Presentation transcript:

OPERATOR OVERLOADING

Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special operations relative to classes that you create. After overloading the appropriate operators, you can use objects in expressions just like built in data types. An operator function defines the operations that the overloaded operator will perform relative to the class upon which it will work. It means performing an operator to work on operands of types it has not yet been designed to operate. e.g. ‘+’ will work on char, int, float, double. It will not work on our ‘String’ class objects s1 = s2 + s3; //will not compile

Operator overloading functions are either member functions or friend functions of that class whose objects are intended as operands of the overloaded operator. The names of the operator-overloading functions are composed of the keyword operator followed by the symbol of the operator being overloaded. operator ( ) ;//prototype ::operator ( ) { // function body } Member functions that overload operators can be private, protected or public

A friend function that overloads a given operator: friend operator ( );//prototyp operator ( ) { // function body } Example of string class – member function class String { public : String operator + (const String &) const; //prototype //rest of class String }; String String :: operator +(const String & ss ) const { // function body } //definition

Then we can use the string object as String s1, s2, s3 ; //String class objects s3 = s2 + s1 ; //call to operator overloading function If it is a friend function – friend String operator + ( const String &, const String &) ; // prototype String operator +(const String&ss1, const String&ss2) { // function body } //definition How the compiler interprets the operator- overloading functions ? s3 =s2 + s1; is interpreted as s3=s1.operator+(s2); if it is a member function

If it is a friend function then s3 = operator + (s1, s2) ; Compiler does not say that invalid operands have been passed to the operator! The operator overloading functions can also be called directly from with in the application programs – the way the compiler interprets it ! s3=s1.operator+(s2); or s3 = operator + (s1, s2) ; We must note that only the name of the operator overloading function is unusual. Otherwise, they are implemented just like ordinary member, non- member or friend functions.

Why friend functions used to overload operators? Let us consider two classes- class A (we defined) and class B(an existing class or an intrinsic datatype) We realize that for some reason only object of class A will be added to an object of class B to get another object of class A : a2 = b1 + a1; Object of class B will not be added to object of class A and b1 will not appear on right of ‘+’ We have no means of modifying the definition of B If we define the member function as follows- class A { public : A operator + ( const B & ) ; } ; //will not compile.

The compiler will interpret the statement a2 = b1 + a1; first as a2 = b1. Operator +(a1) ; and then as a2 = operator + ( b1, a1 ); The prototype of the member function satisfies neither of the two interpretations and compiler will throw an error. Declaring the operator overloading function as a friend function with an object of class B as the first formal argument solves this problem friend A operator + ( const B &, const A &);//PT A operator + ( const B & bb, const A & aa ) { // function body } // defintion

The compiler throws an ambiguity error if both member function and friend functions are used to overload an operator, because both of them will satisfy calls to the overloaded operator. Overview of overloading unary and binary operators Member functions that overload unary operators take no operands, because the calling object is passed as an implicit parameter Friend functions will take one parameter, since the function is invoked without the object reference Similar explanation can be extended in case of overloading binary operators – in member and friend functions

Why are operators overloaded? The operator-overloading functions can be easily substituted by member functions or friend functions with ordinary but meaningful and relevant names : String add(const String & ); //prototype String String :: add(const String & ss ){ }//definition String s1, s2, s3 ; s3 = s1. add (s2) ; This is a substitute to the ‘addition’ operator (+) Operator overloading becomes mandatory under the following circumstances :

(i)Objects of the class acquire resources dynamically during runtime and no two objects should share the same copy of the resource: consider the String class – String s1(“abc”), s2; s2 = s1 ; now both cStr will point to the same block which is undesirable. Hence we defined a suitable copy constructor. The same factors dictate that a suitable function to overload the assignment operator be defined for the ‘String’ (ii) Objects of the class acquire some resources dynamically during runtime and no two objects should share even different copies of the resource:

Imagine that there is a class whose objects should not share even separate copies of dynamically allocated resources. This means even statements o1 = o2 ; // should not compile. The solution is quite simple. We just declare the function to overload the assignment operator in the private section of the class. Any use of the assign- ment operator with in a non-member function will launch a call to this function. Since the function is private, a compile-time error is thrown. If a member or friend function uses the assignment operator, then it can not be prevented. But, it can be prevented by not defining the function to overload=

(iii) Objects need to be passed as parameters in function templates and the operators being used on template class objects with in the template functions should work in the same way on the objects of the class : discussed later (iv) The default action of the dynamic memory management operators( new and delete ) are unsuitable for the class being designed : The new operator throws an exception, if it fails to allocate memory by default. This may be undesirable to the class designed. The class designer may need to call a member function for this. Only overloading ‘new’ fulfill the need

(v) 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 (vi) Overloading provides a better readability of code. o2 = ++o1; better than o2 = o1.pre_fix_increment(); Rules for operator overloading New operators can not be created : creating new operators (such as **) will produce compile time error. void operator ** ( ); //illegal Meaning of the existing operator can not be changed : any operator overloading function 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. In member functions it is automatically enforced. In case of friend functions, the library programmer needs to take extra care. Illegal attempt - friend int operator + (int, int); // error Some of existing operators can not be overloaded : :: (scope resolution). (member selection).*(member selection through pointer to member) ?: (conditional operator) sizeof (size of values) typeid (finding the type of object pointed at)

Some operators can be overloaded using non-static member functions only: = (assignment operator) ( ) (function operator) [] (subscripting operator) -> (pointer to member access operator) these can not be overloaded using friend or static fn. Number of arguments that an existing operator takes can not be changed : statement like void operator / () ; //causes compile time error overloaded operators can not take default arguments : void operator / ( int=0 ) ; //causes compile time error

It is highly imprudent to modify the values of the operands that are passed to the operator overloading functions. Considering the String class- (will not compile) String operator + (String &); // prototype String String :: operator + (String & ss) //definition { …. ; this->cStr =NULL; //bug: LH param changed ss->cStr = NULL; // bug: RH param changed } String operator + (String & const) const ; //correct one the const keyword prevent the bugs and compile.

Overloading the various operators: Increment and decrement operator: Considering the ‘Distance’ class, we can overload the increment operator for objects of the class. If d1 and d2 are objects, then d2 = ++ d1; is interpreted as d2 = d1. operator ++( ) ; Distance operator + + ( ) ; // prototype Distance Distance :: operator ++ ( ) // fn. definition { return Distance (++iFeet, fInches); } Above should not be a constant member function In the function first the iFeet data member of the calling object gets incremented

The explicit call to the constructor creates a nameless object by passing the incremented value of ‘iFeet’ and unaltered value of ‘fInches’ The operator overloading function returns the nameless object thus constructed. If the call is on RHS of assignment operator, the returned object will be copied to the object on the left. If we write d2 = d1 + +; d1 should get incremented after copying to d2. The compiler interprets as d2 = d1. Operator ++(0); It implicitly passes zero as parameter to the call to the overloading function when the postfix notation is used. If it finds a prototype of exact match,

it compiles without warnings or errors. The compiler first looks for a function with an integer as a formal argument provides us with a solution. Formal parameter is a dummy(nameless) class Distance { public : Distance operator + +( ) ; //prefix Distance operator + +(int ) ; //postfix /* rest of class Distance */ }; Distance Distance :: operator + +( ) //prefix { return Distance (++iFeet, fInches) ; } Distance Distance :: operator + +( int ) //postfix { return Distance (iFeet+ +, fInches) ; }

If we provide an operator overloading function for the ‘increment’ operator in prefix notation, we must provide one for postfix notation also. For ‘decrement’ operator – prototype & definitions Distance operator - -( ) ; //prefix Distance operator - -(int ) ; //postfix Distance Distance :: operator - -( ) //prefix { return Distance (- -iFeet, fInches) ; } Distance Distance :: operator - -( int ) //postfix { return Distance (iFeet- -, fInches) ; }

Overloading the unary minus and plus operator class A { int x ; public : A (int = 0 ) ; A operator - ( ) ; } ; A A :: operator – () //member function { return A ( -x ); } For friend function friend A operator – ( const A & ) ; //prototype A operator – (const A & Aobj ) //definition { return A(- Aobj. x ) ; }

Overloading the Arithmetic operators In a member function, the right hand side operand of the operator appear in list of formal arguments In a friend function, both operands will appear class Distance //overloading thro member function { int iFeet; float finches; public: Distance (const int = 0, const float = 0.0 ); void setFeet(const int=0); int getFeet() const; void setInches(const float=0.0); float getInches() const; Distance operator + (const Distance) const };

Distance Distance :: operator + (const Distance dd1) { const return Distance ( iFeet + dd1.iFeet, fInches + dd1.fInches ); } now we can create objects and call function Distance d1(5,8), d2(4,6), d3; d3 = d1 + d2 ; If we pass 2 nd parameter a float value then above code will not work because d3 = d ; will be interpreted as d3 = d1. operator + (4.5) ; and compiler will throw an error. To solve this problem we need to introduce a suitable constructor that converts from float to ‘Distance’ type

Distance :: Distance (const float p) { iFeet = (int) p; fInches = ( p – iFeet ) * 12 ; } If the left hand side operator is of float type, then it should be replaced with a friend function. friend Distance operator + (const Distance, /*prototype */ const Distance ) ; Distance Distance :: operator + (const Distance dd1, { const Distance dd2) return Distance ( dd1.iFeet + dd2.iFeet, dd1.fInches + dd2.fInches ); } This will tackle all the three conditions of d1 & d2. Now if both operands are float type values - then

The operator overloading mechanism will not be invoked, instead values get added to each other. d3 = ; will turn into d3 = 8.0 ; and the constructor that takes float value as parameter and initializes the object with it will be called. Such a constructor is called implicit constructor. Overloading the Relational operators These are binary operators. The syntax is similar to that of the arithmetic binary operator. Considering the class Distance, the function to overload ‘>’ enum bool {false, true}; class Distance { … bool operator > (const Distance )const;//prototype};

bool Distance::operator>(const Distance dd1)const { if(iFeet*12 + fInches > dd1.iFeet*12 + dd1.fInches) return true; return false; } d1>d2 ; d1>4.5 ; This will work if RHS operator is a ‘Distance’ object. If it is a float type value, then it will not compile. Introducing a suitable constructor will solve the problem. What about 4.75 >d1 ? We need to replace it with a friend function bool operator>(const Distance dd1,const Dist dd2) { if(dd1.iFeet*12 + dd1.fInches > dd2.iFeet*12 + dd2.fInches) return true; return false; }

All four possibilities as in ‘+’ operator Overloading Assignment operator It is a binary operator and must be overloaded by a non-static member function only. //prototype class_name & operator = (const class_name &); By default, the compiler generates the function to overload the ‘assignment’ operator if the class designer does not provide one. It carries out a simple member-wise copy. class A { public : A & operator =(const & ); }; A & A :: operator = (const A & rhs) { * this = rhs; return this; }

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; }

if ( ss.cStr != NULL) { len = ss.len; cStr = new char[len + 1]; strcpy(cStr, ss.cStr) ; } } return *this; } 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.

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

(iii) 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. 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.

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.

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

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.

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

The insertion and Extraction operators: for insertion operator : class A { public : //prototype friend ostream & operator <<(ostream &,const A&); //rest of class A }; ostream & operator<<(ostream & dout, const A & AA) {// rest of the function return dout; } The statement cout << A1; is interpreted as operator << (cout, A1); (without const) Same syntax for extraction also ( ‘din’ and ‘>>’ )

These are overloaded using friend functions The objects of the classes ‘istream’ and ‘ostream’ are passed and returned by reference – because the copy constructor and the assignment operator have been declared as protected members in both the classes. This prevents two objects unnecessarily sharing even different copies of the same stream. ostream dout = cout ;; // ERROR istream din ; din = cin ; //ERROR The compulsion to return by reference if the object is returned by value, then a separate object is created in stack. Then call to the copy constructor.

However, the copy constructor is a protected member! Therefore the object must be returned by reference and not by value. But why should the object be returned? Can it be - friend void operator << (ostream &,const A &) ; void operator << (ostream & dout, const A & AA) {//definition of the function } // yes! how will we chain the operator? cout<<A1<<A2; will be interpreted as operator << (operator << (cout, A1), A2) ; if the inner nested call returns ‘void’ instead of ‘ostream &’ how will the outer call execute?

The > are overloaded to achieve data abstraction – a complete independence between the interface and implementation. The signatures and return types of member functions do not change even if the data members with in the class do. Changes in the internal representation of data members of a class do not force its client programs to change. These need not be aware of these. Considering the class ‘String’ and getString() – the function will return a char* (string is stored in a null terminated memory block of characters). If the string is stored in wide characters, then statement cout << s1.getString()<< endl; will no longer work.

If the data type changes, the existing clients fail! If the statement is written as cout<<s1<<endl; then the responsibility of displaying the data is shifted to the object itself. In the actual programming world, libraries are provided as DLL. They do not form the part of the executables physically. They exist separately. Operator overloading, together with DLLs, enables a library programmer in achieving complete data abstraction. A friend function as an alternative to operator overloading : print(cout,s1); friend ostream& print(ostream&,const String&);

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 static void * operator new(size_t); //prototype void * :: operator new(size_t size) { //definition of function }

static void * operator new[](size_t); //prototype void * :: operator new[](size_t size) { //definition of function – for array } static void operator delete(void*, size_t); //prototype for delete void :: operator delete(void * p, { //definition of function } size_t size) static void operator delete[](void*, size_t); //prototype for delete void :: operator delete[](void * p, { //definition of function } size_t size)

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 : static 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; }

#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.

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 : static 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); }

#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.

The statement delete Aptr; is translated as A:: ~A(Aptr); //destructor called for nameless object A:: operator delete (Aptr, sizeof (A) ); //nameless object destroyed Consider the class ‘String’, cStr is the pointer data member. If access is allowed to the private data member in the ‘new’ operator function, the class designer may accidentally allocate memory in heap and make cStr point at it. Now when the constructor is called, a memory leak will occur. So, to prevent this, first any allocated memory must be deallocated and cStr should be assigned with NULL. The drawback of this is – the above will be true, if

the object is created with ‘new’ operator. If the objects are created in the normal fashion : A A1; then ‘cStr’ containing some value, does not mean that, it is definitely pointing to a valid memory block of memory. ‘cStr’ is simply a rouge pointer and using ‘delete’ on this will lead to a run-time error. For such reasons, c++ compiler prevents access to non-static data members by treating the operator ‘new’ and ‘delete’ functions as static. Values are passed to the constructor in the usual way even after the ‘new’ operator is overloaded. A* Aptr = new A(10,20); is translated as A* Aptr =A:: operator new; A:: A (Aptr,10,20);

In order to deallocate the correct amount of memory, the ‘delete’ operator must know the size. The compiler prefixes the size of the memory allocated by ‘new’. The memory used for this becomes a bottleneck in applications where memory is critical. If ‘new’ allocates an array of objects, then one memory slice will be sufficient to store the size. The class designer can ensure that when ‘new’ called for the first time, a memory block to hold a large number of objects gets allocated and the address of the memory block gets returned. The subsequent calls will return address of next block.

When once the memory pool gets exhausted, another pool will get allocated. ‘new’ and ‘delete’ functions get inherited. class A { int x; public: void setx(const int = 0); int getx () const ; static void operator new(const size_t); static void operator delete (void * const size,const size_t);}; class B : public A { int y ; public : void sety(const int=0); int gety(); };

void main () { B * Bptr01 = new B; delete Bptr01; } output : operator new of class A called operator delete of class A called How this can be a problem? void main () { B * Bptr01 = new B; B * Bptr02 = new B; Bptr02->setx(20); cout getx()<< endl; Bptr01->sety(10); cout getx()<< endl; } Output : why??

In order to neutralize the effect of inheritance, the size of memory block being targeted for allocation and deallocation should be compared with the size of the class for which the operator is being overloaded. If these two do not match, then the global ‘new’ or ‘delete’ should be called. Overloading the subscript operator: class { public : operator[] ;}; operator[] {// statements } The function must be a non-static member of the class.

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.

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 but should not To prevent this we should make the return type reference ‘const’. The formal argument of the function that overloads the ‘subscript’ operator can be of any type such as int, char, float, double.

Overloading pointer-to-member(->) operator (smart pointers): It is a postfix unary operator. It is overloaded as #include”String.h” class StrPtr { String * p; public : StrPtr (String & ss) { p= ss ; } String * operator -> () {return p; } }; These can be designed to inevitably point at valid objects. The ordinary pointers have to be explicitly initialized, tested for validity before every use.

Now the client can create the object of the class- String s1(“abc”); StrPtr p(s1); p->setString(“def”) ; In case of ordinary pointers, there is no guarantee that the pointer being used is pointing at valid block of memory. If you try to initialize an object of class ‘StrPtr’ results in compile time error StrPtr p; // error; no zero-arg constructor void f1(StrPtr p) { p-> setString(“abc”); //p is definitely valid }