Module 7 — Challenge Problems¶
Open problems. More than one defensible answer exists, and the reasoning is assessed as much as the code. Each one is designed so that a quick answer is visibly insufficient.
X1 — find the missing virtual, and say how you found it [L4 Analyze]¶
The problem. The code below is compiled, tested, and reviewed. It prints
person: Ayesha Khan for a manager, account: 0 for a savings account, and
vehicle: 200000 for a motorbike. Three hierarchies, three symptoms, one cause between
them — and one of the three has a second cause that the first cause hides.
class Person { public: std::string label() const { return "person: " + name_; } };
class Account { public: long long interest() const { return 0; } };
class Vehicle { public: long long rate() const { return 200000; } };
What a good answer contains.
- The three call sites, each written as a declared-type line: static type,
virtualyes/no, handle form. The answer is not "addvirtualin four places" — it is which line decides each symptom. - The second cause, which the first one conceals: at least one of the three call
sites also copies the object, so adding
virtualalone will not fix it. Say which, and whatsizeofwould have told you sooner. - A rule you can apply to code you did not write. Something greppable: every public function of a base class is either virtual or commented as deliberately not, or no parameter or container takes a polymorphic type by value.
- One counter-example. A base class in the standard library with a non-virtual
function that must stay non-virtual, and why
virtualthere would be wrong. (There are several; the interesting part is your reason.)
Would make it weak. A list of edits with no diagnosis; calling all three symptoms "the same bug"; or a rule that a reviewer could not apply to a diff.
Deciding it for yourself. Write your answer as the review comment you would leave.
If the comment is "add virtual", you have the fix and not the diagnosis.
X2 — the interface that is worth its cost [L5 Design]¶
The problem. You are designing a media player for the university's lecture-capture system. The inputs are: a local file, an HTTP stream, and a capture device. Each can play, pause, seek and report a duration — except the capture device, which cannot seek and whose "duration" is unknown until it stops.
Design the interface. Then argue the other side.
What a good answer contains.
- The split that reflects reality, not a
MediaSourcewith four functions where one implementation throws.PlayableandSeekable, orplay/pause/stopplus an optional capability query — either is defensible, and the answer must say which it chose and what the caller must now do. - Where the failure goes. A source that cannot seek must be unusable as a seekable source rather than failing at run time — this is the module's business, since it is the difference between a compile error and a silent wrong answer. Module 8 names the mechanism.
- Ownership, as in X1 of the exercises: what the player owns, what it borrows, and what a caller must keep alive.
- The argument against your own design: what a single wide interface would have made simpler, and what evidence would make you choose it instead.
- A test for the design: a fourth source (a screen recording with a known duration) that implements the interface with no stubs and no throwing functions. Name the file it goes in and what changes.
Would make it weak. An interface whose first implementation has throw std::logic_error("not
supported") in a method; an answer that never names what it costs; or naming the
interfaces after implementations (FileSourceInterface, HttpSourceInterface).
X3 — when not to use virtual dispatch [L8 Evaluate]¶
The problem. Write the design memo from exercise X3 in full, for a team that has
just learned virtual and wants to use it everywhere. Your reader is competent and
sceptical: they will accept a rule with evidence and reject a slogan.
Cover, at minimum: value types and why a Money with a vtable is a mistake; hot paths
and what evidence justifies the extra indirection; the difference between an operation
that is expected to vary and one that merely could; and what a class with virtual
functions can no longer do — be copied freely, be stored by value, be sorted by value,
be constexpr.
What a good answer contains.
- Measured or cited claims only. "Virtual calls are slow" without a number is not
admissible; a
sizeoftable and a timing loop are, as are citations from Further Reading. - At least one recommendation for virtual dispatch, argued: a place where the cost is worth paying and why.
- Two greppable review rules, and an example diff each would catch.
- The honest complication: a type used polymorphically and stored in bulk wants two types, not one, and the memo should say how you would know.
How you will be judged. Whether a reader who disagrees can follow the reasoning, whether every performance claim is backed by something checkable, and whether the rules could be applied mechanically to a diff.
The rubric¶
Applied to X1, X2 and X3 alike. Score each row 2 (done), 1 (present but weaker), 0 (absent).
| Criterion | |
|---|---|
| 1 | The symptom is restated in one sentence before any fix appears |
| 2 | Every claim is checkable — a compiler message, a measurement, a named source |
| 3 | The diagnosis names the mechanism, not just the edit that removes the symptom |
| 4 | At least one alternative is described fairly enough that its advocate would recognise it |
| 5 | The condition that would reverse the decision is named |
| 6 | The answer says what a reader can do next: a rule, a test, or a file to change |
X1 has a correct diagnosis, so rows 1–3 carry most of the marks. X2 and X3 have no correct verdict, so rows 4 and 5 do.
Evaluating your own answer¶
Write these three lines before reading any suggested approach:
Then compare against the "what a good answer contains" list, item by item, and mark each one present, missing, or present but weaker than the list. The third category is where the marks are: an answer that says "the static type decides" but cannot say which expression's static type, and why a named object behaves differently from a reference, has the vocabulary and not the model.
Two questions to close with:
- Could a reader who disagreed with you still follow your reasoning? If your answer only works for someone who already agrees, it is a preference, not an argument.
- What would make you change your mind? A concrete observation — a profile, a
sizeof, a compiler message you did not expect — not "more experience".
Next: Self-assessment — ten questions, including three predictions and one hunt for a silent failure. · All modules