Quiz 16 — Answers¶
Q1 — B, defined exactly once. Across the whole program a non-inline function or
object must have exactly one definition (the ODR). It may be declared many times (that is
what headers are for), but defined once. Violating it produces a "multiple definition" link
error.
Q2 — True. inline (on a function or variable) permits its definition to appear in
several translation units; the linker keeps one copy. This is exactly how
header-defined functions and class member functions work.
Q3 — A, B, D. A class declaration (A), a function template's definition (B — the
compiler must see it to instantiate), and an inline function used by several files (D) all
belong in a header. A large one-file implementation (C) belongs in a .cpp, so it is
compiled once and not copied into every translation unit.
Q4 —
next() pre-increments the member and returns it: the first call returns 1, the second
returns 2. (If the evaluation order of the two calls were unspecified, the printed order
could differ, but the values are 1 and 2.)
Q5 — Including shapes.h twice in one translation unit re-declares struct Colour
twice, producing a redefinition error:
Fix: add an include guard (#pragma once, or #ifndef/#define/#endif) at the top of
the header, so its contents are seen at most once per translation unit.
Q6 — Because the file format is an implementation detail that will change — from flat text to JSON, to a database — and the domain rules must not change when it does. The infrastructure/persistence layer is what should know the format; the domain declares an interface (a repository) and the infrastructure implements it. The dependency points inward, so the domain can be tested with an in-memory fake, with no file at all.
Q7 — A non-inline global defined in a header is defined in every translation unit that
includes it, so the linker reports a multiple definition error:
Two fixes: (1) declare it extern in the header and define it once in a .cpp; or (2)
make it inline in the header (inline int thing = 0;), which allows several definitions
and keeps one.
Q8 — Dependencies point inward, towards the domain: infrastructure (persistence, UI, files) depends on the domain, never the reverse. It points that way because the domain is the part that is stable and valuable, and because a domain that depends on a detail cannot be tested or reused without that detail.
Q9 — Three layers: a domain (Equipment, Member, Loan, Maintenance), an
application layer (use-case coordinators), and an infrastructure layer (file
persistence, console). The infrastructure layer knows the file format; the domain does not.
One testing interface: an EquipmentRepository (or Storage) abstract base declared in the
domain and implemented in infrastructure, so a test can substitute an in-memory fake. A
Clock interface serves the same purpose for time-dependent rules.
Q10 — Any three credible ones, e.g. the program builds with the course's flags and no warnings; it has a design diagram and a written statement of each class's responsibility; ownership of every resource is explicit; it handles the failure paths (bad input, missing file), not only the happy path; and each rule is covered by a test that fails when the rule is broken. "It compiles" is the floor, not the finish line.
Marking. One point per question (Q3 all-or-nothing). Then read Marking Yourself.