70 likes | 269 Views
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 ?:
E N D
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