Skip to content

Final Self-Assessment

A comprehensive check across the whole course: 25 questions mixing recall, prediction, debugging and design. It is meant as a closing self-check, not an exam — nothing is marked but by you.

Work through it in one sitting, ideally a few weeks after finishing Module 16, and check the answers only when you are done. Then score yourself with Marking Yourself.

Suggested time: 90 minutes, closed-book, no compiler.


Part A — Recall (Q1–Q10)

Q1. (MCQ) Which sequence is the build pipeline?

  • A. compile → link → preprocess
  • B. preprocess → compile → link
  • C. link → compile → preprocess
  • D. preprocess → link → compile

Q2. (true/false) A missing function definition is reported by the compiler, not the linker.

Q3. (MCQ) Which is the surest sign that a class is not encapsulated?

  • A. it has a constructor
  • B. its data members are private
  • C. it returns a mutable reference to its internal data
  • D. it has a destructor

Q4. (multiple-select) Which of these does a class need to write by hand if it owns a raw newed buffer and must copy and move correctly? Select all that apply.

  • A. destructor
  • B. copy constructor
  • C. copy assignment
  • D. move constructor
  • E. a toString() method

Q5. (MCQ) Which pointer expresses "shared, and destroyed when the last user leaves"?

  • A. std::unique_ptr
  • B. std::shared_ptr
  • C. std::weak_ptr
  • D. a raw pointer

Q6. (true/false) A template's definition may safely live in a .cpp file used by another translation unit.

Q7. (multiple-select) Which are exception-safety guarantees? Select all that apply.

  • A. basic
  • B. strong
  • C. nothrow
  • D. deferred

Q8. (MCQ) Which container keeps keys sorted with O(log n) lookup?

  • A. std::vector
  • B. std::unordered_map
  • C. std::map
  • D. std::list

Q9. (MCQ) "A subclass must be usable anywhere its base is expected" is which principle?

  • A. Single Responsibility
  • B. Liskov Substitution
  • C. Interface Segregation
  • D. Open/Closed

Q10. (short answer) State the One Definition Rule in one sentence.

Part B — Prediction (Q11–Q16)

Q11. Write the 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 c; }

Q12. What does this print, and why is it not woof?

#include <iostream>
#include <string>
#include <vector>
class Animal { public: virtual std::string speak() const { return "..."; } virtual ~Animal() = default; };
class Dog : public Animal { public: std::string speak() const override { return "woof"; } };
int main() {
    std::vector<Animal> zoo;
    zoo.push_back(Dog{});
    std::cout << zoo[0].speak() << '\n';
}

Q13. Write the two output lines.

#include <iostream>
#include <memory>
int main() {
    auto sp = std::make_shared<int>(7);
    std::weak_ptr<int> wp = sp;
    std::cout << "count " << sp.use_count() << '\n';
    sp.reset();
    std::cout << (wp.lock() ? "alive" : "gone") << '\n';
}

Q14. Write the output.

#include <iostream>
class Base {
public:
    Base() { who(); }
    virtual void who() const { std::cout << "base\n"; }
    virtual ~Base() = default;
};
class Derived : public Base {
public:
    void who() const override { std::cout << "derived\n"; }
};
int main() { Derived d; }

Q15. Write the two output lines.

#include <algorithm>
#include <iostream>
#include <vector>
int main() {
    std::vector<int> v{5, 1, 4, 2, 3};
    std::sort(v.begin(), v.end());
    auto n = std::count_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
    std::cout << v.front() << ' ' << v.back() << '\n';
    std::cout << n << '\n';
}

Q16. Write the two output lines.

#include <iostream>
#include <utility>
class H {
public:
    explicit H(int id) : id_(id) {}
    H(H&& o) noexcept : id_(o.id_) { o.id_ = -1; }
    ~H() { if (id_ != -1) std::cout << "close" << id_ << ' '; }
    int id() const { return id_; }
private:
    int id_;
};
int main() {
    H a{3};
    H b = std::move(a);
    std::cout << "a" << a.id() << ' ' << "b" << b.id() << '\n';
}

Part C — Debugging and analysis (Q17–Q21)

Q17. State the defect and the fix.

class Base { public: ~Base() { } };
class Derived : public Base { public: ~Derived() { } };
int main() { Base* p = new Derived; delete p; }

Q18. State the defect and the fix.

#include <functional>
std::function<int()> makeCounter() {
    int count = 0;
    return [&]() { return ++count; };
}

Q19. State the defect and the fix.

struct Base { void show() const {} };
struct Derived : Base { void show(int) const {} };
int main() { Derived d; d.show(); }

Q20. (analysis) A comparison used by std::sort is written as return a.value() <= b.value();. Explain why this is wrong and what can happen.

Q21. (analysis) A class holds only std::string and std::vector members. Which of the five special members should it write, and why?

Part D — Design (Q22–Q25)

Q22. (design) Give the interface (name and signatures) for a MediaSource with open, play, pause, stop, and one failure rule every implementation must respect.

Q23. (design) Events are consumed by several observers, more will be added, and one must unsubscribe at run time. State the observer interface and the two safety rules (unsubscription and ownership).

Q24. (design) A shipping-cost function has an if per method and is edited every quarter. Describe the refactoring and what a caller does to add a fifth method.

Q25. (design) State the layers of a well-structured application, the dependency direction between them, and where file persistence belongs.


Then: check your answers against the answer key, and score yourself with Marking Yourself.