I had a midterm in c++ and one of our assignments was to write a class, that overloads the <<
operator so that we could print private fields of that class to std::ostream
, like so:
Crate c1(2600, 9500);
Crate c2;
cout << c1 << ", " << c2 << endl;
had to print Crate weight: 2600 Crate value: 9500, Crate weight: 0 Crate value: 0
My implementation of this was
class Crate {
int weight;
int value;
public:
Crate ():weight(0), value(0) {}
Crate (int w, int v);
Crate& operator+= (Crate& c);
int operator+= (int& w);
friend ostream& operator<< (ostream& out, Crate c) {
out << "Crate weight: " << c.weight;
out << " Crate value: " << c.value;
return out;
}
};
However, I got 0/3 points for the overloaded <<
operator, and the only difference between my solution and the evaluation template was that I pass Crate c
by value and they passed it by reference.
Of course, if the class would have dynamically allocated member variables, I would have to pass instances of it by reference, but this is not the case here.
I know that the example provided at cppreference.com uses a const reference, but is there any strict rule that one MUST use a const reference when doing this?
I understand that my solution copies both weight
and value
to the stack instead of only copying a pointer to the object, but is +4 bytes (in case of a 32 bit system) on the stack really that much of a problem, or am I missing something much more serious (like a memory leak of some sort)?
I also checked the disassembly of both solutions, but I couldn't find anything that would make my solution worth zero points.
I have also asked my professors but they started to talk about passing it as const
but I don't see how that would make this solution any better in terms of works / doesn't work. An other professor told me that "this is syntactically completely incorrect." however it compiled with Visual Studio and MinGW, so I can't make any sense of that either.
Please also note that this is a course for electrical engineers.
Is it obligatory to pass classes by reference in c++
No.
"Passing it as const" that's just silly, if you're passing by value then it doesn't matter to the outside world if you mark the parameter as const.
To answer your question as directly as possible, it is not wrong to take the other class by value. When the objects are smaller it's better to pass by value. In your case the size difference is 0 on a typical 64-bit platform (2 * 4bytes per int vs one 8 byte pointer). So your "+4 bytes on the stack" actually doesn't exist, it's the same size
I'd predict an optimizing compiler to rewrite your code to take the Crate
by value, even if you declared it as taking by reference. This would be for spatial locality reasons and ease of access. If a pointer is passed, you'd need to follow the pointer to get to the data members, which adds a step.
Your professor is wrong to give you 0 points for this, unless there was some requirement made very clear in the course that all operators must take reference parameters. The const Crate
vs Crate
issue doesn't matter.
You should not have received a 0 but you should not have received full credit either.
friend ostream& operator<< (ostream& out, Crate c)
Is going to create a copy every time you call it which can be inefficient. To avoid those copies you want to pass by reference like
friend ostream& operator<< (ostream& out, Crate& c)
But this introduces a new problem that your first version didn't have as to pass by reference you need to supply an lvalue to the function. You would not be able to use it like
std::cout << Crate();
To combat that we can take the Crate
by const &
which will avoid copies and allow us to bind to temporaries
friend ostream& operator<< (ostream& out, const Crate& c)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With