March 1, 2002
Reading assignment:
Deitel and Deitel - 8.1-8.3 and 8.7-8.8 again
-or-
Other texts: overloading binary operators
Warm-up: Last time we overloaded the + and == for a class of Complex numbers.
Note that operator+ really should have been a const member function.
Now, overload the - operator in this same class:
class Complex {
public:
Complex(float r=0, float i=0) {real=r, imag = i;}
void display() const {cout << real << " + " << imag << "i ";}
void set_real(float r, float im) { real = r; imag = im;}
Complex operator+(const Complex &c) const;
Complex operator-(const Complex &c) const;
bool operator==(const Complex &c) const {return (c.real==real &&c.imag==imag);};
private:
float real;
float imag;
};
Complex Complex::operator+(const Complex &right) const
{
Complex ans;
ans.real = real+right.real;
ans.imag = imag+right.imag;
return ans;
}
Complex Complex::operator-(const Complex &right) const
{
Complex ans;
ans.real = real-right.real;
ans.imag = imag-right.imag;
return ans;
}
int main()
{
Complex c1(2), c2(2,4), c4(2, 4), c3;
cout << "Testing the + operator: " << endl;
c3 = c1+c2;
c1.display(); cout << " + "; c2.display(); cout << " = "; c3.display(); cout << endl;
c3 = c1-c2;
c1.display(); cout << " - ("; c2.display(); cout << ") = "; c3.display(); cout << endl;
if (c4==c2) cout << "Yeah! == works! " << endl;
if (!(c1==c2)) cout << "Yeah! == works" << endl;
return 0;
}
Notice that having to use the Complex::display operator is really irritating. It
would be much better if we could just say cout << c1. This requires overloading the
<< operator, which we'll learn next week.
Now we'll overload some other operators for the class Complex. Overloading =, +=,
etc. has an extra complication. Let's start with the assignment operator. (Please
note that this is not actually necessary for class Complex - because the assignment
operator is automatically provided (member-wise copy) in a reasonable way for classes
that contain no pointer data members.)
If I say a=b, the compiler translates it to a.operator=(b). So we have to create
a member function called "operator=" Our first guess for the declaration might be
void Complex::operator=(const Complex &);
However, it has to satisfy an extra requirement - we have to be able to
"cascade" assignments
x = y = z; (which means x = (y = z);)
So after doing the assignment (changing the value of a to the value of b), if we return
a copy of the left-hand variable, then this allows us to subsequently assign it to
another variable. Our second guess for the declaration is
Complex &Complex::operator=(const Complex &)
On the other hand, if we write
(x = y) = z;
this shouldn't even compile, because (x=y) is not an lvalue. We can avoid this problem
by making the return value const - here's the final definition:
const Complex &Complex::operator=(const Complex&right)
{
if (this != &right) { // if the left and right are the same, then don't copy
real = right.real; // do a memberwise copy
imag = right.imag;
}
return (*this); // this enables cascaded calls
}
Now here's an overloading of += (note that this function returns a constant - which
disables statements such as (x+=y)+=z
const Complex &Complex::operator+=(const Complex &right)
{
real += right.real; // add components of right operator to
imag += right.imag; // the components of this operator
return *this;
}