Reputation: 2593
const Byte operator/(const Byte& right) const {
require(right.b != 0, "divide by zero");
return Byte(b / right.b);
}
I read that If the effect of the operator is to produce a new value, you will need to generate a new object as the return value. For example, Integer::operator+
must produce an Integer
object that is the sum of the operands. This object is returned by value as a const
, so the result cannot be modified as an lvalue.
What if we don't write it as const
? Any example with explanation would be helpful.
Also why do we have second const
in function prototype?
Upvotes: 3
Views: 2053
Reputation: 254431
Any example with explanation would be helpful.
This is outdated advice, intended to make the operator behave somewhat like the built-in operator so that nonsense like (a / b) = c
won't compile.
However, since C++11, it also inhibits move semantics, which can hurt efficiency; so you shouldn't return a const
value.
Also why do we have second const in function prototype?
The argument is a const
reference, and the member function is const
, to (a) ensure that the operator doesn't modify either operand; and (b) allow it to be called with constant or temporary operands.
To elaborate on (b), without these const
qualifiers, you wouldn't be able to use constant operands:
const Byte a, b;
a / b; // ERROR: operands can't be const
or temporary values:
Byte f();
f() / f(); // ERROR: operands can't be temporary
Upvotes: 9
Reputation: 42924
For binary operators, I'd prefer defining a "free" (non-member) function (that may be friend
of the class on which it operates, in case it needs to directly access the private
or protected
data members of the class):
class Byte {
....
friend Byte operator/(const Byte& left, const Byte& right) {
require(right.b != 0, "divide by zero");
return Byte(left.b / right.b);
}
};
Both left
and right
parameters are passed by const &
because:
const
&
Anyway, if your Byte
class just wraps an 8-bit byte, and the copy constructor is a trivial one-byte copy, you can simplify your code and just pass by value:
friend Byte operator/(Byte left, Byte right) {
require(right.b != 0, "divide by zero");
return Byte(left.b / right.b);
}
Upvotes: 1