p3-euchre
Operator Overloading
In this project, you implement an output operator <<
and comparison
operators <
, <=
, >
, >=
, ==
, and !=
for the Card
class.
This appendix provides a quick tutorial on operator overloading with
a simple Thing
class as an example. We recommend you use these same
patterns for your Card
class.
Stream insertion operator
In C++, we use the stream insertion operator <<
(AKA output operator) to print built-in types. For example:
cout << "My favorite number is " << 42 << endl;
We can also use this convenient mechanism for our own custom types.
Consider a simple class called Thing
that keeps track of an ID
number:
class Thing {
int id; //Things store their ID number
public:
Thing(int id_in) : id(id_in) {} // constructor
int get_id() const { return id; }
};
We can add a function that lets us print a Thing
object using
cout
, or any other stream. This is called an overloaded output
operator. Notice that this is not a member function.
std::ostream& operator<< (std::ostream& os, const Thing& t) {
os << "Thing # " << t.get_id(); //send output to "os"
return os; //don't forget to return "os"
}
Now, we can print Thing
objects just as conveniently as we can print
strings and integers!
int main() {
Thing t1(7);
cout << t1 << endl; //use overloaded output operator
}
This produces the following output:
Thing # 7
Comparison operators
Let’s say that we also want to be able to check if two Thing
objects
are equal. For this, we’ll overload the ==
operator. Notice that this is not a member function.
bool operator==(const Thing& first, const Thing& second) {
return first.get_id() == second.get_id();
}
Now, we can easily check two Thing
objects for equality:
int main() {
Thing thing_1(42);
Thing thing_2(42);
Thing thing_3(43);
cout << thing_1 == thing_2 << endl; // true
cout << thing_1 == thing_3 << endl; // false
}
Likewise, we could define a <
operator to compare two Thing
objects. In this case, we
bool operator<(const Thing& first, const Thing& second) {
return first.get_id() < second.get_id();
}
What about the rest of the comparison operators? There are
six total operators, but we can actually implement the remaining
four by calling the two we’ve already done (==
and <
).
bool operator<=(const Thing& first,const Thing& second) {
return first < second || first == second;
}
bool operator>(const Thing& first, const Thing& second) {
return !(first <= second);
}
bool operator>=(const Thing& first, const Thing& second) {
return !(first < second);
}
bool operator!=(const Thing& first, const Thing& second){
return !(first == second);
}
Implementing the equality and comparison operators this way is highly recommended! Reusing code where possible means fewer lines to write and fewer places for bugs to hide!