Quiz 5 — Answers¶
Q1 — C, operator=. Assignment must be a member because the compiler supplies a
non-member one only for the implicit form, and because a = b; must be able to reach the
class's own assignment. The other three can each be written either way (operator+ and
operator== are often better as free functions; operator<< must be a free function,
since the stream is the left operand).
Q2 — False. operator< must be a strict ordering: a < a must be false. Using <=
makes it true, which violates the requirement std::sort relies on, and the result is
undefined behaviour. It is not a style question.
Q3 — A, B. A symmetric operator+ (A) benefits from being free, because the compiler
can convert either operand. operator<< (B) must be free, because its left operand is
the stream, not your object. operator= (C) and operator[] (D) must be members.
Q4 —
1250 + 175 = 1425. price < tax is 1250 < 175 = false, printed as 0. price == price
is true, printed as 1. Note that all three operators had to exist for this to compile —
without operator< and operator==, the comparison lines would not build.
Q5 —
issued_ starts at 100. Each Ticket construction pre-increments it, so the first ticket
is 101 and the second is 102. issuedCount() after both is 102. This is class-level state:
one counter for the class, not one per object.
Q6 — The comparison uses <=, so a < a is true. std::sort requires a strict weak
ordering, and a "less-than" that is true for equal elements violates it — the algorithm is
then free to do anything (undefined behaviour), including appearing to work. Fix:
Q7 — For a member operator+, the left operand is always the current object: m + 2
means m.operator+(2), and 2 can be converted to a Money. But 2 + m would need 2 to
be a Money already, and a member function cannot be found on an int. Making operator+
a free function Money operator+(const Money&, const Money&) lets the compiler apply
the same conversion on whichever side needs it.
Q8 — operator<< must return std::ostream& — the stream itself. That is what makes
std::cout << a << b; work: the first << must yield something the second << can use as
its left operand. Returning void (or anything else) breaks chaining.
Q9 —
After ++c and c++, n_ is 2. Then Counter d = c++; copies the current value (2) into
d, and increments c to 3 — so the final line shows c at 3 and d at 2. That is why
postfix must copy first: it returns the value before incrementing.
Q10 — Store the amount as an integer number of cents, so arithmetic is exact and no
rounding creeps in. Provide the operators the desk uses: +, -, comparison (==, <),
scaling by an integer, and << for printing. Enforce "never negative" in the constructor
and in the subtracting operation. Do not provide operator* between two Money values
(money × money is meaningless) or an implicit conversion from double (it would reintroduce
rounding). A design that overloads everything is not a design.
Marking. One point per question (Q3 all-or-nothing). Then read Marking Yourself.