Skip to content

Quiz 3 — Constructors and Destructors

Ten questions on how objects are born and how they die. Several ask you to predict the order of construction and destruction — write it down before you check.

Attempt all of them closed-book, then mark yourself against the answers.

Concepts: default and parameterised constructors · delegating constructors · member-initialiser lists · construction and destruction order · temporary objects.


Q1. (MCQ) When are a class's members constructed relative to its constructor body?

  • A. after the body runs
  • B. before the body runs
  • C. in the order the initialiser list mentions them
  • D. it depends on the compiler

Q2. (predict) Write all four output lines.

#include <iostream>

class Engine {
public:
    Engine()  { std::cout << "engine on\n"; }
    ~Engine() { std::cout << "engine off\n"; }
};

class Car {
public:
    Car()  { std::cout << "car on\n"; }
    ~Car() { std::cout << "car off\n"; }
private:
    Engine engine_;
};

int main() {
    Car car;
}

Q3. (true/false) A destructor must be called explicitly before an object goes out of scope.

Q4. (multiple-select) Which of these are good reasons to initialise a member in the member-initialiser list rather than assigning it in the constructor body? Select all that apply.

  • A. The member has no default constructor
  • B. The member is a reference or const
  • C. It avoids default-constructing and then overwriting the member
  • D. It changes the order of construction to match the list

Q5. (predict) Write the line this prints.

#include <iostream>

class Box {
public:
    Box() : b_(a_ + 1), a_(5) { std::cout << a_ << ' ' << b_ << '\n'; }
private:
    int a_;
    int b_;
};

int main() {
    Box box;
}

Q6. (short answer) What is a delegating constructor, and what does it avoid?

Q7. (analysis) A class has two constructors that both std::cout a message. One delegates to the other. How many messages print when the delegating one is called, and why?

Q8. (debug) One member is assigned in the body instead of initialised. Rewrite the constructor so every member is initialised in the list.

#include <iostream>

class Reading {
public:
    Reading(int value) { value_ = value; }
    int value() const { return value_; }
private:
    int value_;
};

int main() {
    Reading r{20};
    std::cout << r.value() << '\n';
}

Q9. (predict) Write the output, in order.

#include <iostream>

struct Noisy {
    int id;
    explicit Noisy(int i) : id(i) { std::cout << "make " << id << '\n'; }
    ~Noisy() { std::cout << "drop " << id << '\n'; }
};

int main() {
    Noisy a{1};
    {
        Noisy b{2};
        Noisy c{3};
    }
    Noisy d{4};
}

Q10. (design) A Logger acquires a buffer in its constructor. Decide where the buffer should be released, and justify your choice in two sentences. Name one thing a caller would have to remember if you chose otherwise.


Scoring: mark yourself with the answers, then read the self-assessment guide.