Transcript Training

Operator Overloading
What is operator overloading?
•
Most predefined operators (arithmetic, logic, etc.) in C++ can be
overloaded when applied to objects of a class by providing an operator
function. Examples of those that can not be overloaded are ::, . , and ?:
•
Operators keep their predefined precedence and associatively
class X{public:
X operator -(); // unary -ve operator invoked by X a; -a;
X operator ++(); // prefix increment invoked by X a; ++a;
X operator ++(int); // postfix increment, X a; a++;
X operator -(X&); // binary -, X b; a - b ;
X operator +(X&); // add operator, a + b;
// The return type X is needed to cascade operators
// global functions can also be used to overload operators on objects
Operator Overloading
A simple example:
class Complex{
double real, imag;
public:
Complex(double r=0.0, double I=0.0){real = r; imag = I;}
Complex operator ++(){real += 1.0; imag += 1.0; return *this;}
Complex operator +(Complex& c){
Complex temp;
temp.real = real + c.real;
temp.imag = imag + c.imag;
return temp; // this invokes the default copy constructor
// can also be implemented in one line as
return Complex(real + c.real , imag + c.imag); } };
main(){ Complex
c1(1.5,2.0), c2(1.2,2.2), c3;
c3 = ++c1 + ++c2; //why the ++ functions must return a Complex data type
Operator Overloading
What happens when the assignment exists as in operators +=,
-=, *=
assume we will add the following member functions to class Complex
Complex& operator +=(Complex&);
Complex& operator -=(Complex&);
Complex& operator *=(Complex&);
Complex& Complex::operator +=(Complex& a){
real += a.real; imag += a.imag
return *this;}
Complex& Complex::operator *=(Complex& a){
real = real*a.real - imag * a.imag; // there is an error here
imag = real * a.imag + imag * a.real;
return *this;}
Operator Overloading
The indexing operator [] for an array
class Vector{ float *p; int size;
public:
Vector(int n){ p = new float[n]; size=n;}
~Vector() {delete p;}
float& operator [](int I){return p[I];}
Vector operator +(const Vector & a){ Vector temp(size);
for(int I=0; I<size; I++) temp.p[I] = p[I] + a.p[I];
return temp; // this will destroy the resulting Vector why?
// a default copy constructor will be used to copy the attributes p and size
// only
// To remedy this, a special copy constructor must be defined as follows,
Vector(Vector& c){p = new float[c.size], size = c.size;
for(int I=0; I<size; I++) p[I] = c.p[I];
}// this will form a new dynamic object for the result
Operator Overloading
The assignment operator
Although the assignment operator is supported by a default copy
operator, the following example will produce a Null pointer assignment
fun(){ Vector x1(20), x2(10); x2 = x1;
// now x2.p and x1.p have the same address, size = 20
}// the destructor function will be called once for x1 and once for x2
// upon function exit, the same array will be deleted twice
The following assignment operator function is needed to remedy this
Vector& operator = (const Vector& a){
if(this != &a){// check that this is not x=x
delete p; // clean up
p = new float [size = a.size];
for(int I =0;I<size;I++) p[I] = a.p[I];}
return *this;}
// every class should contain a copy constructor and an assignment operator
Operator Overloading
Non-member operator functions
used to define operations between different types of objects
e.g.
Vector operator * (const Matrix& a, const Vector& b){
Vector temp;
for(int I = 0; I < a.no_rows; I++)
for(int j = 0; j < a.no_cols; j++)
temp[I] = a[I][j] * b[I];
return temp;
}
The above function should be declared as friend function in both class
matrix and class vector as follows,
class Matrix{…friend Vector operator * (const Matrix&,const Vector&);}
class Vector{…friend Vector operator * (const Matrix&,const Vector&);}
Operator Overloading
Overloading the stream input/output operators >> and <<
this is needed to apply these operators to the instances of objects
e.g., Complex x(0.0,0.0); cin >> x; cout << x; // this needs the following
functions which input or outputs complex numbers as (flt.pt , flt.pt.)
istream& operator >> (istream& input, const Complex& a){
double re=0,im=0; char c;
input >> c; // input a character in c
if(c == ‘(‘ ){ input >> re >> c; // input real part followed by ,
if ( c == ‘,’ ) {input >> im >> c; // input imag part followed by )
if ( c == ‘)’ ){ a = Complex(re,im); return input;}}}
cout << “error in input format”;
}
ostream& operator << (ostream& output, const Complex& a){
return output << ‘\n’ << ‘(‘ << a.real << ‘,’ << a.imag << ‘)’ << ‘\n’;
}// the above functions must be declared as friends in class Complex