It would be more convenient to use "==" instead of "equal".
But "==" isn't defined on objects of type money (only
on built-in types).
The compiler wouldn't know what it "means" to ask if
two money objects are the same.
But you can tell it…
We can overload operators such as ==, +, *, =, and [].
Remember that "overload" means to supply an additional
meaning applicable to different types of data. In this case
we give a new meaning to an operator (like "==") in the
case that the type of data involved is an object of type money.
Here's how:
class Account {
public:
friend bool operator ==(const Acount& act1,
const Account& act2) const;
friend Account operator +(const Acount& act1,
const Account& act2) const;
...
}
The word "operator" signals to the compiler that an operator
symbol is the function to be overloaded. In other respects it
looks like any other function prototype.
Note that operator == is a friend -- it is not a member of the class!!
Here is the actual body of the code (outside the class):
bool operator == (const Acount& act1,
const Account& act2) const
{
return (act1.balance == act2.balance);
}
Account operator + (const Acount& act1,
const Account& act2) const
{
Account temp;
temp.balance = act1.balance + act2.balance;
return temp;
}
Account act1, act2, act3, act4;
...
if (act1 == act2) ...
...
act4 = act1 + act2 + act3;
or
if (operator==(act1,act2)) .. // name of function is operator==
...
act3 = operator+(act1,act2); // name of funciton is operator+
Some
rules:
- you cannot define new operators
- "friend" is not required
- one of the parameters must be of a class type
- you cannot change the number of arguments or the precedence of the operator.
The output (<<) and input (><) and input (>>) operators can also be overloaded.
class Account {
public:
friend ostream& operator<<(ostream& outs, const Account& act);
friend istream& operator>>(istream& ins, Account& act);
...
}
Account act1;
cin >> act1;
cout << act1;
First,
consider insertion operator <<. ><
Notice that the function returns an ostream&, and also takes an
ostream&
as a parameter.
Why is the ostream parameter a reference? The output operator will
change the output stream:
ostream& operator<<(ostream& outs,
const Account& act) const
{
outs << "The balance is:" << act.balance;
return outs;
}
...
cout << act1;
Since
cout is changed, parameter outs should be a reference (so outs and
cout refer to the same object.)
Why do we return a reference to an ostream object? Output expressions can
be chained:
cout << act1 << act2 << act3;
This is the same as:
((cout << act1) << act2 ) << act3
That is:
The result of (cout << act1) must be an object into which
we can insert
The only kind of object into which we can insert is a stream
Therefore (cout << act1) must return a stream!
Therefore the operator << must return a stream.
The stream it returns is cout -- i.e. it returns the same stream we
give it.
ostream& operator<<(ostream& outs, // we give it outs
const Account& act) const {
outs << "The balance is:" << act.balance;
return outs; // and it returns the same stream
}
...
cout << act1; // cout is the ostream argument
Since
we use "ostream&" as the parameter type and the return type:
- parameter outs is another name for argument cout
- the returned object is another name for parameter outs
==> the returned object is another name for argument cout,
i.e., we return cout.
The extraction operator is overloaded the same way:
class Account {
public:
friend ostream& operator<<(ostream& outs, const Account& act);
friend istream& operator>>(istream& ins, Account& act);
...
}
//Account act1;
//cin >> act1;
//cout << act1;
istream& operator>>(istream& ins, Account& act) {
ins >> act.balance;
return ins; // return the argument
}
We
return an istream reference since input operations can also be chained:
cin act1 >> act2 >> act3;
Next: Example Class with Overloading
Slide 6