March 8, 2002
Reading assignment:
Deitel and Deitel - Read 8.5
Other texts - overloading the << and >> operators
Overloading the << operator
- We'll overload the << operator for the class Complex, shown here
class Complex {
friend ostream &operator<<(ostream &out, const Complex &c);
friend istream &operator>>(istream &in, Complex &c);
public:
Complex(float r=0, float i=0) {real=r, imag = i;}
Complex operator+(const Complex &c) const;
bool operator==(const Complex &c) const {return (c.real==real &&c.imag==imag);};
// etc., other member functions left off for brevity
private:
float real;
float imag;
};
Complex Complex::operator+(const Complex &c) const
{
Complex ans;
ans.real = real+c.real;
ans.imag = imag+c.imag;
return ans;
}
ostream &operator<<(ostream &out, const Complex &c)
{
out << c.real;
if (c.imag) cout << " + " << c.imag << 'i';
return out;
}
istream &operator>>(istream &in, Complex &c)
{
float real_part(0), imag_part(0);
char ch1, ch2;
// read in the real part, the plus sign, the imaginary part, and an 'i'
in >> real_part >> ch1 >> imag_part >> ch2;
c.real = real_part;
c.imag = imag_part;
return in;
}
- Remember that if we say x op y, the compiler translates it to x.operator op(y)
In other words, the member function operator op is called for the left operand
But when we say cout << obj, the left operand is cout, not obj. This means that
we can't implement it as a member function of obj. Instead, we overload << with
a non-member function. If such a function has been written, then the compiler will
turn x.operator op(y) to operator op(x,y)
- This non-member function must take the two operands as parameters. Remember that
cout is an ostream, so the first parameter is an ostream. This first parameter
cannot be const, since we are altering it by writing to it! The second parameter is
the object, in our case, a Complex object. It should be const, because the object
itself should not be altered just because we are displaying it.
- We want to be able to cascade << (like the case of the assignment operator),
so the function must return a reference to the ostream
- Since the function is no longer a member function, we don't have to worry about
whether the function itself should be declared const
- The declaration is thus
ostream &operator<<(ostream &out, const Complex &c);
- If we make this a friend function, then it can access the data members
and display them
- Now we can output complex numbers with code such as:
Complex c1(2,4);
cout << c1;
Overloading the >> operator
- We'll now overload the >> operator for the class Complex
- Again, this non-member function must take the two operands as parameters. Remember
that cin is an istream, so the first parameter is a (non-const) istream &.
As before, the second parameter is a Complex &, but this time we expect the second
parameter to be changed, so it is no longer const
- We want to be able to cascade >> as well, so the function must return a reference
to the istream
- The declaration is thus
istream &operator>>(istream &input, Complex &c);
- If we make this a friend function, then we can set the private data
members to the values input from the stream
- Look at the function definition - note that it currently does no error checking
and requires you to enter a real and imaginary part (even for 0+0i)
- Now we can output complex numbers with code such as:
Complex c1;
cin >> c1;