I'd like us to write a class called Date. This class will be used to store normal calendar dates. The class should contain three private data variables:
It should also contain the following public member functions:
Beyond that, feel free to build the class however you want. I'm planning to add a private member function
bool isValidDate(unsigned inMonth, unsigned inDay, unsigned inYear)
to help make the code easier to read.
As per usual, we're going to build this together and talk about the different decisions we make as we go. You can find the final result below.
Add a public member function called incrementDate. This should change the date to whatever the next calendar date happens to be. For example:
Date date(1,4,2009); date.incrementDate(); // now date is 1/5/2009 Date date2(3,31,2015); date2.incrementDate(); // now date2 is 4/1/2015
First let's start with an example. Remember how + works with strings? '+' is called an operator. Honestly, this is pretty much same thing as a function. It accepts two parameters (string1 and string2), and returns a string. We're going to learn how to write our own operator functions. The syntax will be different than normal functions, but the background idea of inputting parameters and returning something is the same.
To see a full list of operators and find out which ones are overloadable, check out this Wikipedia link. There are quite a few! This link is also pretty helpful, because it tells you what the prototype of your operator function looks like. In particular, the prototype is different depending on if your operator is a member function of a class, or just a regular function.
We're going to start out with a straightforward example. We'll write a '+' operator that works for vector<int>. The idea will be the same as for strings. It will input two vectors, and return the concatenation. Below is the finished code.
Now we're going to add some operators to our Date class that we just built.
We're going to overload the '==' operator so that it works with Date objects. In other words, we're going to write some code that will handle the expression
date1 == date2
where date1 and date2 are both of type Date. Below is the finished version.
Here's how this function works. If I write
firstDate == secondDate
It will look inside the firstDate object, and will run the operator== function where the input variable date2 is the same as secondDate. This is because firstDate is on the left-hand side of the == sign, and secondDate is on the right.
Some tricky questions:
Next we're going to overload the < operator. Our code will handle expressions of the form
date1 < date2
Let's say that this is true when date2 is further in the future than date1. For example, 5/8/1990 < 4/2/2000.
For the >= operator, we should be able to use our previous code to quickly get a solution. We already can calculate (date1 == date2) and (date1 < date2), so we should be able to combine these to get one-line definition for >=
However, to do this we're going to have to learn one more bit of notation. Let's say my two date objects are called date1 and date2. If I run the code
date1 >= date2
then I know that date2 is the input parameter to the function. But how do I refer to date1? When working inside of main, this object is called date1. But my >= function runs from inside of date1, and this is a different scope. Calling it date1 here would be an error.
The answer is *this. In member functions of classes, if you want to refer to the object that you are currently working inside, use *this.
Finished Code: Date.cpp Date.cpp dateTest.cpp
We'll define the ++ operator for our Date class. It'll have the same effect as the incrementDate() function that talked about above.
The ++ operator is a little more complicated than the operators we dealt with above. One problem is that i++ (called the postfix increment operator) and ++i (called the prefix increment operator) represent different things. This means they must have different prototypes (they can't both be operator++()). c++ fixes this issue by adding a "dummy variable" to the prototype for i++. This is an extra integer in the list of parameters that is completely unused. It's kind of an ugly solution, but that's the way it is.
So in order to write a member function of Date that handles
We are required to use the prototype
Date operator++(int x)
See the table of overloadable operators again to check out the difference between the prefix and postfix increments.
Once we're all okay with the prototype, we can write the function. But be careful: this operator has return type Date. So at the end of your function you must return a Date object (it should be the edited Date).