C++/Programming Issues
Expert: Zlatko - 4/9/2010
QuestionQUESTION: I'm fairly new to programming, really don't understand most of it. I've attempted a program that I'm not quite sure if I've satisfied the requirements because it simply just don't look right, please help me.
Design a class called NumDays. The class ‘s purpose is to store a value that represents a number of work hours and convert it to a number of days. For example, 8 hours would be converted to 1 day, 12 hours would be converted to 1.5 days, and 18 hours would be converted to 2.25 days. The class should have constructor that accepts a number of hours, as well as member functions for storing and retrieving the hours and days. The class should also have the following overloaded operators:
+ Addition operator: When two NumDays objects are added together, the overloaded +
operator should return the sum of the two object’s hours member.
- Subtraction operator: When one NumDays object is subtracted from another, the
overloaded – operator should return the difference of the two objects hours member.
++ Prefix and postfix increment operators. These operators should increment the number
of hours stored in the object. When incremented, the number of days should be
automatically re-calculated.
-- Prefix and postfix increment operators. These operators should decrement the number
of hours stored in the object. When decremented, the number of days should be
automatically re-calculated.
This is what I have:
#include <iostream>
#include <math.h>
using namespace std;
class NumDays
{
private:
double hrs, days;
public:
NumDays(double h)
{
hrs = h;
days = hrs*1.0/8;
}
double getHrs(){return hrs;}
double getDays(){return days;}
NumDays operator +(NumDays n2)
{
double h;
h = hrs + n2.getHrs();
return NumDays(h);
}
NumDays operator ++()
{
double h=hrs;
++h;
days=hrs/8;
cout<<endl<<h<<endl;
return NumDays(hrs);
}
NumDays operator ++(int i)
{
double h=hrs;
++h;
NumDays d=NumDays(hrs);
hrs = h;
days = h/8;
return d;
}
NumDays operator --()
{
double h=hrs;
--h;
hrs=h;
days=hrs/8;
cout<<endl<<h<<endl;
return NumDays(hrs);
}
NumDays operator --(int i)
{
double h=hrs;
--h;
NumDays d=NumDays(hrs);
hrs =h;
days = h/8;
return d;
}
};
int main ()
{
NumDays d1(16);NumDays d2(8);
NumDays d3 = d1 + d2;
cout<<"After addition number of days is :" <<d3.getDays()<<endl;
++d3;
cout<<"After pre increment numof days is : "<<d3.getDays()<<endl;
d3++;
cout<<"After post increment numof days is :"<<d3.getDays()<<endl;
system("pause");
}
ANSWER: Hello Alex. I like your question because it made me think.
You did a pretty good job, but there are some things that should be corrected. Your version of the pre-increment operator is:
NumDays operator ++()
{
double h=hrs;
++h;
days=hrs/8;
cout<<endl<<h<<endl;
return NumDays(hrs);
}
The pre and post increment operators are supposed to modify the object, and return the object. They are not supposed to return a new modified object. You probably noticed that code like this:
NumDays d1(16);
cout << d1.getHrs() << endl;
++d1;
cout << d1.getHrs() << endl;
prints 16 twice. In fact the d1 object was not incremented. What happened was that a new NumDays was returned and thrown away. A better, but not perfect version is this:
NumDays operator ++()
{
++hrs;
days=hrs/8;
return *this;
}
Notice it is the object itself being modified and returned, but what is being returned is still a copy. Now the code below prints 16 and 17
NumDays d1(16);
cout << d1.getHrs() << endl;
++d1;
cout << d1.getHrs() << endl;
Now, let me show you the behavior of pre-increment on integers. Generally, when possible, your operator overloading should match the behavior of built in types.
int i = 0;
++++i;
cout << i << end;
the above prints 2. The double pre-increment worked on the i twice. This would not happen with the NumDays pre-increment. The compiler would accept ++++d1, but the result would still be one increment of d1. The reason is that the first pre-increment works on d1, and the second works on the copy of d1 returned from the first pre-increment. We must return d1, not a copy, from the pre-increment operator so that the second pre-increment also works on d1.
The correct code is this:
NumDays& operator ++()
{
++hrs;
days=hrs/8;
return *this;
}
What is the difference ? The only difference is that the return type is NumDays&, not NumDays . We are returning a reference to the incremented object, not a copy of the incremented object. It is tricky.
Now on to post increment. The post increment is supposed to return the original value, before the increment. Therefore it must return a copy, but the copy must be made before the increment happens. Lets go back to the integer example. Notice that the compiler will not accept integer post-increment like this i++++. There is a reason, but never mind, for now you should emulate the behavior. To make it so, the post-increment must return a const object. The correct code is:
const NumDays operator ++(int i)
{
NumDays original = NumDays(hrs);
++hrs;
days = hrs/8;
return original;
}
Now, you go ahead and fix the decrement functions but remember that when decrementing, things can go negative. If it doesn't make sense to have negative hours, then you must not allow the decrement when the hours are already 0.
Finally, when a function does not change any of the data in an object, the function should be declared const. It is just a minor thing. So the code
double getHrs(){return hrs;}
double getDays(){return days;}
should look like this
double getHrs() const {return hrs;}
double getDays() const {return days;}
If something I've written is confusing, just ask about it.
Best regards
Zlatko
---------- FOLLOW-UP ----------
QUESTION: #include <iostream>
#include <math.h>
using namespace std;
class NumDays
{
private:
double hrs, days;
public:
NumDays(double h)
{
hrs = h;
days = hrs*1.0/8;
}
double getHrs() const {return hrs;}
double getDays() const {return days;}
NumDays operator +(NumDays n2)
{
double h;
h = hrs + n2.getHrs();
return NumDays(h);
}
NumDays& operator ++()
{
double h=hrs;
++h;
days=hrs/8;
cout<<endl<<h<<endl;
return *this;
}
const NumDays operator ++(int i)
{
NumDays original = NumDays(hrs);
++hrs;
days = hrs/8;
return original;
}
NumDays& operator --()
{
double h=hrs;
--h;
hrs=h;
days=hrs/8;
cout<<endl<<h<<endl;
return *this;
}
const NumDays operator --(int i)
{
NumDays original = NumDays (hrs);
--hrs;
days = hrs/8;
return original;
}
};
int main ()
{
NumDays d1(16);NumDays d2(8);
NumDays d3 = d1 + d2;
cout<<"After addition number of days is :" <<d3.getDays()<<endl;
++d3;
cout<<"After pre increment numof days is : "<<d3.getDays()<<endl;
d3++;
cout<<"After post increment numof days is :"<<d3.getDays()<<endl;
system("pause");
}
I've written it correctly, but just had a few minor errors. Is this what you mean?
AnswerI'm not sure if you got my last answer. Here is the correct code you should change.
NumDays& operator ++()
{
++hrs;
days=hrs/8;
return *this;
}
const NumDays operator ++(int i)
{
NumDays original = NumDays(hrs);
++hrs;
days = hrs/8;
return original;
}
double getHrs() const {return hrs;}
double getDays() const {return days;}
Don't forget to change the decrement operators to match the increment.