Skip to content

Quiz 10 — Answers

Back to the quiz


Q1 — B, a shallow copy. The default copy constructor copies each member, and for an int* that means copying the address. Both objects then point at one buffer — usually a double free at destruction.

Q2 — True (with a caveat). Declaring a destructor does not delete the copy constructor; the compiler still generates one (deprecated, but present). The danger is that it is a shallow copy. Declaring a destructor does suppress the implicit move operations, which is a different consequence.

Q3 — A, B, C. The Rule of Three says: if you write any one of them you likely need all three (A); it applies to classes that own a resource (B); the three are the destructor, copy constructor and copy assignment (C). It does not require a move constructor (D) — that is the Rule of Five.

Q4 —

copied
42 7

The deep copy constructor allocates a new buffer and copies the values, so b[0] = 7 does not touch a. Without the copy constructor, both would share one buffer and print 7 7 before crashing on the double free.

Q5 —

open 10
move 10
a is -1, b is 10
close 10

The move constructor takes the id (10) and sets the source's id to -1; the destructor stays silent for the moved-from object. Only b, which owns the real resource, prints close. A moved-from object is valid but unspecified — safe to destroy or assign to, not to rely on.

Q6 — On x = x, line (1) frees x's buffer and line (2) then reads from the now-freed storage — undefined behaviour (and the destructor frees it again). Fix with a self-assignment guard:

    if (this == &other) return *this;   // before freeing data_

or use the copy-and-swap idiom, which needs no guard.

Q7 — It needs to write none of them. Members that manage their own resources (std::string, std::vector) already implement the Rule of Five correctly, so the compiler-generated destructor, copy and move are all correct. This is the Rule of Zero.

Q8 — A moved-from object is in a valid but unspecified state: its invariants hold and it can be destroyed or assigned to, but its value is not defined. For unique_ptr and many hand-written types it is empty/null, but you must not rely on any particular value.

Q9 — copy prints twice, then size 2.

copy
copy
size 2

reserve(2) prevents reallocation, so the only copies come from push_back copying its temporary into the vector. Tag declares a destructor and a copy constructor and no move constructor, so push_back copies rather than moves. Two pushes, two copies.

Q10 — Because the grade book holds a std::vector<double> (or similar), it can write none of the five — the Rule of Zero applies. If it must own a raw array, it needs the destructor, copy constructor and copy assignment (Rule of Three), and optionally the move constructor and move assignment (Rule of Five) for efficiency; the move leaves the source empty and destructible. Writing the vector version is preferable because there is nothing to get wrong.


Marking. One point per question (Q3 all-or-nothing). Then read Marking Yourself.