Object Oriented Programming C++ Lecture No 12

Outline:

  • Overloading the Subscript Operator [ ]
  • Overloading the Function Call Operator ( )
  • Overloading Unary Operators

–Overloading Increment ++ operator prefix form

–Overloading Increment ++ operator postfix form

Overloading the Subscript Operator [ ]

  • One of the interesting operators is the subscript operator.
  • It can be declared in two different ways:

class C {

returntype& operator [] ( paramtype);

or

const returntype& operator [] ( paramtype) const;

};

 

  • The first declaration can be used when the overloaded subscript operator modifies the object.
  • The second declaration is used with a const object; in this case, the overloaded subscript operator can access but not modify the object.
  • If c is an object of class C, the expression c[i] is interpreted as

c.operator[ ](i)

  • Example: in the String example below, the subscript operator [] is used to access the ith character of the string.
  • If i is less than zero then the first character and if i is greater than the size of the string the last character will be accessed.

char& String::operator[ ](int i) {

if(i < 0)

return contents[0]; // return first character

if(i >= size)

return contents[size-1];// return last character

return contents[i];// return i th character

}

#include <iostream>
#include <String>
using namespace std;
class String {
     int size;	        // Size of string
	 char *contents; // Pointer to the contents of the string
 public:
	String(const char *);	// constructor
	char& operator[ ](int);  // subscript operator
	void print() const ;
	~String();			// Destructor
};

 

String::String(const char *data)
{
	 cout<< "Constructor has been invoked" << endl;
	 size = strlen(data);
	 contents = new char[size + 1];
	 strcpy(contents, data);
}

String::~String() {
	cout<< "Destructor has been invoked" << endl;
	delete[] contents;
}
char& String::operator[ ](int i)  {
   if(i < 0)
      	return contents[0]; // return first character
	if(i >= size)
		return contents[size-1]; // return last character
	return contents[i]; // return i th character
}

void String::print() const {	 
	cout<< contents << " " << size << endl; 
}
int main() 
{
	 String s1("String 1");
	 s1[1] = 'p'; // modifies an element of the contents
	 s1.print();
	 cout << " 5 th character of the string s1 is: " 
		  << s1[5] << endl;
		// prints an element of the contents
	 return 0;
}

Overloading the Function Call Operator ( )

  • The function call operator is unique in that it allows any number of arguments.

class C

{

returntype operator ( ) ( paramtypes);

};

  • If c is an object of class C, the expression c(i,j,k) is interpreted as

c.operator( )( i, j, k )

  • ComplexNumber Example:

–The function call operator is overloaded to print complex numbers on the screen.

–In this example the function call operator does not take any arguments.

// The function call operator without any argument

void ComplexNumber::operator( )( ) const

{

cout << real << ” , ” << imaginary << endl ;

}

#include <iostream>
using namespace std;
class ComplexNumber {
	double real, imaginary; // real and imaginary parts
 public:
	ComplexNumber(double r=0, double i=0) : real(r),imaginary(i)
		{ };
	ComplexNumber operator+(const ComplexNumber &) const;
	void operator()() const;   
	};

ComplexNumber ComplexNumber::operator+(const ComplexNumber &c) const

{

double r, i;// temporary variables

r = real+c.real;

i=imaginary+c.imaginary;

return ComplexNumber(r,i);

// constructs and returns the result object

}

void ComplexNumber::operator()() const {

cout << “complex number= ”

<< real << ” , ” << imaginary << endl ;

}

int main()
{
 ComplexNumber z1(1,1), z2(2,2), z3;
	z1();
	z2();
	z3 = z1 + z2;
	z3();
	return 0;
}

output;

complex number= 1 , 1

complex number= 2 , 2

complex number= 3 , 3

Press any key to continue

 

  • String Example: The function call operator is overloaded to copy a part of the contents of a string into a given memory location.
  • In this example the function call operator takes two arguments: the address of the destination memory and the numbers of characters to copy.

// The function call operator with two arguments

void String::operator( )( char * dest, int num) const

{

if (num > size) num=size;

// if num is greater than the size of the string

for (int k=0; k < num; k++) dest[k]=contents[k];

}

Example:

#include <iostream>
#include <cstring>
using namespace std;
class String{
	int size;
	char *contents;
 public:
	String(); //default constructor
	String(const char *); // parameterized constructor
	void operator()(char *, int) const;
	~String(); // Destructor
};
// Default Constructor
// Creates an empty string (only NULL character)
String::String()           		   
{
	cout<< "Default constructor has been invoked" << endl;
	size = 0; contents = new char[1];
	strcpy(contents, "");
}
// Parameterized Constructor
String::String(const char *data)
{
	 cout<< "Constructor has been invoked" << endl;
	 size = strlen(data);
	 contents = new char[size + 1];		
	 // allocate memory for the string, +1 is for NULL
	 strcpy(contents, data);
 }
void String::operator()(char * dest, int num) const 
{
 if (num>size) num=size;	
 for (int k=0; k< num; k++)
	  dest[k]=contents[k];
}
String::~String(){
cout<< "Destructor has been invoked" << endl;
delete[] contents;
}
int main()
{
	String s1("Example Program");
	char *c=new char[8]; // Destination memory
	s1(c,7);  // Function call operator is invoked
	c[7]='\0'; // End of String (null)
	cout << c << endl;
	delete[] c;
	return 0;
}

Overloading Unary Operators.

  • Unary operators operate on a single operand.
  • Examples are the increment (++) and decrement (–) operators; the unary minus, as in -5; and the logical not (!) operator.
  • Unary operators take no arguments, they operate on the object for which they were called.
  • Normally, this operator appears on the left side of the object, as in !obj, -obj, and ++obj.
  • Example ComplexNumber: We define ++ operator for class ComplexNumber to increment the real part of the complex number by 0.1
void ComplexNumber::operator++()
{
	real=real+0.1;
}

int main()
{
	ComplexNumber z(1.2, 0.5);
	++z; // operator++ function is called
	z.print();
	return 0;
}

 

  • To be able to assign the incremented value to a new object, the operator function must return a reference to the object.

const ComplexNumber& ComplexNumber::operator++() {

real=real+0.1;

return *this;

}

int main() {

ComplexNumber z1(1.2, 0.5), z2;

z2 = ++z1;

// ++ operator is called, incremented value is assigned to z2

z2.print();

return 0;

}

  • Recall that ++ and — operators come in a “pre” and “post” form.
  • If these operators are used with an assignment statement than different forms has different meanings.
  • z2= ++ z1; // preincrement
  • z2 = z1++; // postincrement
  • The declaration, operator ++ ( ) with no parameters overloads the preincrement operator.
  • The declaration, operator ++ (int) with a single int parameter overloads the postincrement operator.
  • Here, the int parameter serves to distinguish the postincrement form from the preincrement form.
  • This parameter is not used.

 

ComplexNumber ComplexNumber::operator++(int)    

// postincrement operator

{

ComplexNumber temp;

temp = *this; // old value (original objects)

real = real + 0.1; // increment the real part

return temp; // return old value

}

 

Example:

#include<iostream>
using namespace std;
class ComplexNumber {
	double real, imaginary;
 public:
	ComplexNumber(double r=0, double i=0): real(r), imaginary(i)
		{ };						
    const ComplexNumber& operator++(); //pre ++
	ComplexNumber operator++(int);	// post ++
	void print() const;			
};
// preincrement ++
const ComplexNumber& ComplexNumber:: operator++()  
{
	real=real+0.1;
	return *this;
}

void ComplexNumber::print() const
{
	cout << real << " , " << imaginary << endl;
}

 

// postincrement ++

ComplexNumber  ComplexNumber::operator++(int) 

{

ComplexNumber temp;

temp=*this;     // saves old value

real=real+0.1;

return temp;   // return old value

}

int main(){
	ComplexNumber z1(1.2,0.5),z2;
	z2= ++z1;	// operator++() is called
	cout << "After preincrement operation:" << endl;
	cout <<"z1 =";
	z1.print();
	cout <<"z2 =";
	z2.print();
	z2= z1++;	// operator++(int) is called
	cout << "After postincrement operation:" << endl;
	cout <<"z1 =";
	z1.print();
	cout <<"z2 =";
	z2.print();
	return 0;
}

output:

After preincrement operation:

z1 =1.3 , 0.5

z2 =1.3 , 0.5

After postincrement operation:

z1 =1.4 , 0.5

z2 =1.3 , 0.5

Press any key to continue

 

 

End of lecture.

Leave a Reply

Your email address will not be published. Required fields are marked *