PDA

View Full Version : Overloaded Operator Help




DeltaEKs
Feb 23, 2012, 02:39 PM
Once again, Xcode will not understand certain code syntax written on Windows. I'm trying to figure out why this is giving me an error. I do have the prototype declared in a header file:

DateType operator+ (int numDays)
{

}

The error says "overloaded operator must have at least one parameter of class or enumeration type." The error resides after I change the "int" to "DateType" (DateType is the class), but that doesn't really fix the issue. I have a function called AdvanceDays that I'm going to insert numDays into and that will increase the date by x number of days.

Why would this code work automatically on Windows and how can I get it to work on Mac? Sorry for such a noob question.



subsonix
Feb 23, 2012, 02:59 PM
That is not a prototype.

gnasher729
Feb 23, 2012, 05:16 PM
Why would this code work automatically on Windows and how can I get it to work on Mac? Sorry for such a noob question.

The reason is usually that Microsoft C++ compilers are rubbish and don't implement the language properly. But in this case, you can either overload the unary operator+ (the one that is used for +x), then it must either be a class method or a non-class function with a class as parameter, or you can overload the binary operator+ (the one that is used for x+y), then it must be either a class method with one parameter, or a non-class function with two parameters, of which at least one is a class, and you did neither.

But I would bet you meant to write

DateType DateType::operator+ (int numDays) { ... }

or

DateType operator+ (const DateType& date, int numDays) { ... }


and a windows compiler won't compile your code either.

chrono1081
Feb 23, 2012, 05:22 PM
The reason is usually that Microsoft C++ compilers are rubbish and don't implement the language properly. But in this case, you can either overload the unary operator+ (the one that is used for +x), then it must either be a class method or a non-class function with a class as parameter, or you can overload the binary operator+ (the one that is used for x+y), then it must be either a class method with one parameter, or a non-class function with two parameters, of which at least one is a class, and you did neither.

But I would bet you meant to write

DateType DateType::operator+ (int numDays) { ... }

or

DateType operator+ (const DateType& date, int numDays) { ... }


and a windows compiler won't compile your code either.

This!

I started realizing this in my 1st year of my second college.

subsonix
Feb 23, 2012, 06:22 PM
Could also be that the warning levels are different. I don't know if what is shown was referring to the header file or supposed to be some kind of sketch of an implementation with an empty body. Given that you are allowed to have an implementation in the header file, if the posted code is indeed from the header file that might have generated the error (warning ?).

Presumably the date class maintains days since some kind of epoch date, so the implementation could be something like.


DateType &operator+(int numDays) {
this->dayNumber += numDays;
// calculate new date based on days since epoch
return this;
}


Although it would make more sense to add two dates than adding days to a date, but if the prototype looks like this for the above implementation, it should not be a problem.


DateType &operator+(int numDays);

gnasher729
Feb 24, 2012, 12:27 PM
Could also be that the warning levels are different.

I don't think so. The OP says that the error goes away when the parameter is changed from "int" to "DateType". That is exactly what would happen for the definition of a unary operator+

DateType operator+ (DateType x) { return x; }
DateType operator- (DateType x) { throw ("unary minus does not make sense for class DateType"); }
DateType operator+ (DateType x, int days) { calculate and return x + number of days }

subsonix
Feb 24, 2012, 01:34 PM
I don't think so. The OP says that the error goes away when the parameter is changed from "int" to "DateType". That is exactly what would happen for the definition of a unary operator+

DateType operator+ (DateType x) { return x; }
DateType operator- (DateType x) { throw ("unary minus does not make sense for class DateType"); }
DateType operator+ (DateType x, int days) { calculate and return x + number of days }


Yeah, and that suggests that the declaration has an argument that is of type "DateType". But the posted code is claimed to be from the header file, and the argument is int. That is the confusing part, does the types differ in the header and implementation? Who knows, what is posted is not a prototype and since you can include an implementation in the header file that could be it.

If the OP hasn't vanished forever, it would be helpful to update the exact declaration and implementation. ie post exactly what is in the .h and .cpp file, then there is no question about what it is that has been posted.

For what is worth, I have actually overloaded the minus operator for a date type in C++ once. Subtracting two dates would give you the amount of days between the dates. :)

gnasher729
Feb 24, 2012, 02:28 PM
For what is worth, I have actually overloaded the minus operator for a date type in C++ once. Subtracting two dates would give you the amount of days between the dates. :)

Makes totally sense for the binary minus operator - just not for unary minus operator.

DeltaEKs
Feb 24, 2012, 05:41 PM
Sorry for pretending to be dead, I don't check this site very often, haha.

I was not saying that what I posted was a prototype, the prototype is in my header file, I should have made that clearer.

What I'm trying to say is basically I'm a Mac user trying to learn the mac-way of programming in classes primarily geared towards Windows. What I have written down was code copied and pasted from a template our teacher gave us. I was able to overload a bunch of other operators like "<" and ">" etc, but "+" and "-' were the only ones that gave errors like this. Being completely new to overloading, I want to know what I need to get this working on a Mac. I have Windows 7 installed on Bootcamp for emergencies if I really need to switch.

Also, I should not we're using C++.

Let me know what you guys need to know to help me. I'll try to be more responsive, thanks for helping.

EDIT: Ok, actually I tried using this that Gnasher729 posted and it ended up working:

DateType DateType::operator+ (int numDays)

So, now my question is why this specific iteration works while the other one doesn't? Is there a difference?

Sander
Feb 25, 2012, 05:20 AM
Microsoft C++ compilers used to be bad, nowadays they're very good. Microsoft is also focusing a lot of effort on that area; google for "Going Native 2012" which MS hosted.

Back to the original issue: What I think happened is that you have a class definition containing the operator+. When it's inside a class definition, it is assumed that the only argument to the operator is the right-hand-side:


class DateTime
{
...
DateTime& operator+(int rhs);
};


This defines an operator which takes a DateTime object as lhs and an integer as rhs, to be used like this:


DateTime a, b;
...
a = b + 42;


which is actually a syntactic shortcut for


a = b.operator+(42);


Operators need not be class members though, and you are free to define freestanding functions too:


DateTime operator+(const DateTime& lhs, int rhs);


The operator+ and (operator-) are special in that they also exist as unary operators (in the case of the + that's rather academic, in the case of the minus this is so that you can write "-d" where d is a DateTime - whatever that means).

Now, in your .cpp file, you started implementing the operators. But instead of typing this:


DateTime& DateTime::operator+(int rhs)
{
AdvanceDays(rhs);
return *this;
}


(i.e., the implementation of the member), you wrote this:


DateTime operator+ (int rhs)
{
...
}


I.e., a freestanding unary operator taking a single int as argument and returning a DateTime. The compiler hasn't seen the prototype of this function yet, but that doesn't matter: You're allowed to define this new function. But you can't redefine operators which already exist for the builtin types (the int, in this case) so you can't change the meaning of "+42". This is where the error comes from. I'm surprised that you got the same error when you changed that int to DateTime (unless DateTime is not really a class but just a typedef for an int, or something like that).