Reputation: 825
class student
{
private:
int age;
public:
student();
student(int a) {age = a;}
~student() {};
friend student& operator+ (int left, student& s);
friend ostream& operator<< (ostream& o, student& s);
}
...
student& operator + (int left, student& s)
{
s.age += left;
return s;
}
ostream& operator<< (ostream& o, student& s)
{
o << s.age << endl;
}
int main (void)
{
student a (10);
cout << 14 + a ;
return 0;
}
So I have two questions from the above code.
Why do you have to do return s;
in the operator+ (int left, student& s)
function?
why can't you just put the return type as void
since you're already passing student
object by reference?
It seems that I get an error whenever I put endl
after 14 + a
, I catch an error and it doesn't print. I know this has something to do with `operator <<', but I don't know the exact reason for it, and how do you prevent this from happening?
Upvotes: 2
Views: 111
Reputation: 153899
Concerning 1, you don't have to do anything. The language imposes no restrictions on what you do with an overloaded operator. Maintainability and readability, on the other hand, do require that the overloaded operator behave in some way like the corresponding built-in operator. Thus:
It makes no sense to overload addition for a type named
student
, since it makes no sense adding students. (On the
other hand, your class student
really seems more like an
abstraction of StudentAge
.)
Addition (operator +
) does not modify either of its
arguments. With almost no exceptions. In your case (supposing
StudentAge
, rather than just Student
), I could see three
operators: StudentAge operator+( StudentAge const& lhs, int rhs
)
, StudentAge operator+( int lhs, StudentAge const& rhs )
,
and above all, StudentAge& StudentAge::operator+=( int rhs )
.
The last would change this
, and the first two should
probably be implemented in terms of this third overload.
All of the overloaded addition operators should return
something, because this is what the built-in operator does.
operator+
returns a new object, and operator+=
returns
a reference to this
(return *this;
). Again, always.
Anything else is abuse, and only serves to confuse the reader.
With regards to your second question: you've declared
operator<<
to return something, so implement it to return
something. Just falling off the end is undefined behavior (even
without anything else following).
Upvotes: 1
Reputation: 126412
Why do you have to do return s; in the operator+ (int left, student& s) function?
I must say your definition of operator +
is strange, as it modifies the right side object - while operator +
normally does not, and returns a new object by value.
Anyway, operator +
normally does not return void
so that it allows chaining, as in:
14 + (16 + a)
But again, operator +
is not supposed to modify the right side object. You probably meant to write something like operator +=
. Consider changing the definition of your operator +
.
It seems that I get an error whenever I put endl after 14 + a, I catch an error and it doesn't print. I know this has something to do with `operator <<', but I don't know the exact reason for it, and how do you prevent this from happening?
Your program has undefined behavior, because your overload of operator <<
does not return anything. You should add a return statement:
ostream& operator<< (ostream& o, student const& s)
// ^^^^^
{
o << s.age << endl;
return o;
// ^^^^^^^^^ <== Without this, your program has undefined behavior.
// Value-returning functions MUST return a value (with
// the only exception of main())
}
Also, as done above, you should accept the student
object by reference to const
, since the operator <<
is not going to alter its state (if you didn't do that, you could not use operator <<
with a const
object.
Upvotes: 6
Reputation: 478
For 1), consider the following code :
student aStudent = anotherStudent + aDifferentStudent;
Here, we take two arguments and return a value. This is why you need to return an instance of the class. Your current implementation is not a standard way of doing the operator+ function, as it modifies the arguments. Consider the string operator+ used here:
std::string aString = "Hello" + " " + "World";
Operating from right-to-left, " " and "World" are literal strings, passed to the function, which returns " World", which is then passed along with "Hello" to the function again (as you have 2 calls to the operator+ method) to finally return "Hello World". Your implementation cannot do that, as A) the function parameters are not declared const, and B) if they were, and it did a const-cast to modify, you'd be attempting to modify a string literal - undefined behaviour.
String is a good example of how one expects the operator+ overload to work, in order to avoid breaking the principal of least surprise.
As for your << and endl issue, this is similar in principal. You need to return the o instance.
Upvotes: 0