210 likes | 335 Views
Engineering Problem Solving With C++ An Object Based Approach. Additional Topics Chapter 10 Programming with Classes. Overloading Operators. Allows a programmer defined data type to be used in the same way that a predefined data type is used.
E N D
Engineering Problem Solving With C++An Object Based Approach Additional Topics Chapter 10 Programming with Classes
Overloading Operators • Allows a programmer defined data type to be used in the same way that a predefined data type is used. • Definitions for operator functions are included in a class definition in the same way as member functions • keyword operator is used followed by the name of the function. • the name of the function is one of the predefined C++ operators • Only predefined operators may be overloaded • All predefined operators except( . :: .* ?: sizeof) may be overloaded.
Complex Number Class • A complex number is a number that has two components; the real component and the imaginary component. • a + bi • Arithmetic is defined as follows: • (a + bi) + (c + di) = (a + c) + (b + d)i • (a + bi) - (c + di) = (a - c) + (b - d)i • (a + bi) * (c + di) = (ac - bd) + (ad + bc)i • (a + bi) / (c + di) = (ac + bd) / (c**2+d**2) + • [ (bc -ad) /(c**2+d**2)]i
Class Declaration class complex { public: complex(); complex(double,double); void print(ostream&); void input(istream&); complex operator+(complex&) const; complex operator-(complex&) const; complex operator*(complex&) const; complex operator/(complex&) const; private: double real, imag; };
Implementation - constructors • complex::complex() : real(0), imag(0) • { //default constructor • } • complex :: complex(double r, double im) : • real(r), imag(im) • { //parameterized constructor • }
Implementation – Overloaded Operators • complex complex::operator+(complex& c) const • { • complex temp; • temp.real = real + c.real; • temp.imag = imag + c.imag; • return temp; • }
Implementation - Continued • complex complex::operator/(complex& c) const • { • complex temp; • temp.real = (real*c.real + imag*c.imag)/ • ( pow(c.real,2) + pow(imag,2) ); • temp.imag = (imag*c.real - real*c.imag)/ • ( pow(c.real,2) + pow(imag,2) ); • return temp; • }
Practice! – Implement the * operator(a + bi) * (c + di) = (ac - bd) + (ad + bc)i complex complex::operator*(complex& c) const { complex temp; temp.real = real*c.real – imag*c.imag; temp.imag = real*c.imag + imag*c.real; return temp; }
Test Program complex c1, c2, c3; //declare three complex variables c1.input(cin); c2.input(cin); //test addition c3 = c1 + c2; // using overloaded operator + cout << endl << "c1 + c2 is "; c3.print(cout); //test division c3 = c1 / c2; // using overloaded operator / cout << endl << "c1 / c2 is "; c3.print(cout); cout << endl;
Sample Output • Using the following input: 4.4 1.5 3.5 -2.5 • The expected output from our test program will be: c1 + c2 is 7.9 + -1i c1 / c2 is 0.62973 + 0.878378i
Variations • Overloading Operators as: • member functions • friend functions • top level (non-member) functions
Member Functions • binary operators (ie +,-, * ) • member function requires one argument • the left hand operand is the object invoking the operator • unary operator • member function requires no arguments • assumed to be prefix version of operators ++ and – • postfix versions of operators ++ and – are not covered in this text • Disadvantages • first argument must be an objectof the class
Example – class complex • In complex.h • complex operator +(complex c); • operator + implemented in complex.cpp • In a client program complex a, b, c; c = a + b; //a is calling object, b is argument c = a + 54.3; //OK, constructor is called to // convert 54.3 to complex object c = 54.3 + a // is not allowed
Friend Functions • binary operators • friend function requires two arguments • unary operator • friend function requires one argument • Disadvantage • A friend function is NOT a member function • Friend functions violate a strict interpretation of object oriented principals (implementation is hidden) • Recommended for operator overloading only
Example: • In class definition: friend complex operator +(complex c1, complex c2); • In class implementation: complex operator +(complex c1, complex c2) { complex temp; temp.real = c1.real + c2.real; temp.imag = c1.imag + c2.imag; return temp; } • In client program: complex cA, cB, cC; cC = cA+cB; cC = 54.3 + cB;//this is ok, when + is a friend function
Class Declaration class complex { public: complex(); complex(double,double); friend ostream& operator <<(ostream&, complex); friend istream& operator >>(istream&, complex&); complex operator+(complex&) const; complex operator-(complex&) const; complex operator*(complex&) const; complex operator/(complex&) const; private: double real, imag; };
Implementation ostream& operator <<(ostream& os, complex r) { os << r.real << “ + “ << r.imag << ‘i’; return os; } istream& operator >> (istream& is, complex& r) { is >> r.real >> r.imag; return is; }
Error Checking on input operator • If your input fails because of incorrect format, your function should mark the state of the istream as bad is.clear(ios::badbit | is.rdstate() ) • clear resets entire error state to zero • clear(ios::badbit) clears all and sets badbit • is.rdstate() returns the previous state of all bits • Statement sets the bit vector to the bitwise OR of badbit with previous state • Failure can be tested with is.fail()
Top Level (Non-Member) Functions • binary operators • top level function requires two arguments • unary operator • top level function requires one argument • Disadvantage: • Top level functions do not have access to private data members. Function must use accessor functions.
Example of top level function • Function prototype in client program. complex operator +(complex c1, complex c2); • Implemention in client program. complex operator +(complex c1, complex c2) { return complex(c1.get_real() + c2.get_real(), c1.get_imag() + c2.get_imag()); } • Use in client program. complex cA, cB, cC; cC = cA + cB; cC = 54.3 + cA;//this is ok, when + is a top level //function