AI InterviewSearch…Search problems, topics, or pages…Ctrl KGet started
Skip to content

08 Classes and objects / Checkpoint

Checkpoint — Classes and objects

25 min · +25 XP · 3 exercises · 14 questions

Exercises0/3
Quiz · 70% to clear14 q

This checkpoint covers the whole module: structs, aggregates and designated initialisers, constructors and the member-initialiser list, this and const-correctness, static members, encapsulation with friends, and the header/source split behind a worked design.

How it works. Fourteen questions and three programs. You need 70% on the questions and every program accepted to clear the module. You can retake it as often as you like; your best score counts.

Before you start, make sure you can answer these from memory:

  • What are the only two differences between struct and class?
  • In what order are members initialised, and what does the order of the member-initialiser list change?
  • Why does Money m = 5; fail when the constructor is explicit, while Money m{5}; works?
  • What type does this have inside a const member function?
  • Why does a chaining mutator return T& rather than T?
  • What goes wrong when an instance counter is incremented in the constructor but copying is left to the compiler?
  • Which operand of operator<< makes it impossible to write as a member?

The three programs are a gradebook whose Student chains add() and validates every mark, a Grid with const and non-const at() and a half-turn written as one chain, and an assembly line whose instrumented parts show the construction and destruction order of a class with three members and a static count. Trace the instrumented one on paper before you run it.

Common questions

Why does Money m = 5; fail when the constructor is explicit?

Money m = 5; is copy-initialisation, which needs an implicit conversion from int to Money, and explicit forbids exactly that. Money m{5}; is direct-initialisation: it calls the constructor by name, so explicit does not block it.

What type does this have inside a const member function?

Inside a const member function of class T, this is a const T*, a pointer to a const object. Every data member is therefore read-only there, except members declared mutable, and only other const member functions can be called.

Why does a chaining mutator return T& rather than T?

Returning T& with return *this; hands the next call the same object, so every call in the chain modifies it. Returning T by value hands back a copy: the rest of the chain modifies temporaries and the original object is left unchanged, with no compiler error.

What are the only two differences between struct and class in C++?

Default member access — public in a struct, private in a class — and default inheritance, which is likewise public for a struct and private for a class. Everything else, including member functions and constructors, is identical.

C++ Classes and Objects Quiz: Constructors and Const Practice

Test your knowledge of C++ classes with 14 questions and three programs on structs, constructors, this and const, static members, friends and headers.

  • Course: C++ study plan
  • Module: Classes and objects
  • Kind: Checkpoint — cleared at 70%
  • Reading time: 25 min
  • Runtime: Clang 18 · C++20

Checkpoint — Classes and objects is the checkpoint that closes the Classes and objects module: a graded quiz and whole-program exercises, passed at 70%.

Instructions

This checkpoint covers the whole module: structs, aggregates and designated initialisers, constructors and the member-initialiser list, this and const-correctness, static members, encapsulation with friends, and the header/source split behind a worked design.

How it works. Fourteen questions and three programs. You need 70% on the questions and every program accepted to clear the module. You can retake it as often as you like; your best score counts.

Before you start, make sure you can answer these from memory:

  • What are the only two differences between struct and class?
  • In what order are members initialised, and what does the order of the member-initialiser list change?
  • Why does Money m = 5; fail when the constructor is explicit, while Money m{5}; works?
  • What type does this have inside a const member function?
  • Why does a chaining mutator return T& rather than T?
  • What goes wrong when an instance counter is incremented in the constructor but copying is left to the compiler?
  • Which operand of operator<< makes it impossible to write as a member?

The three programs are a gradebook whose Student chains add() and validates every mark, a Grid with const and non-const at() and a half-turn written as one chain, and an assembly line whose instrumented parts show the construction and destruction order of a class with three members and a static count. Trace the instrumented one on paper before you run it.

Common questions

Why does Money m = 5; fail when the constructor is explicit?

Money m = 5; is copy-initialisation, which needs an implicit conversion from int to Money, and explicit forbids exactly that. Money m{5}; is direct-initialisation: it calls the constructor by name, so explicit does not block it.

What type does this have inside a const member function?

Inside a const member function of class T, this is a const T*, a pointer to a const object. Every data member is therefore read-only there, except members declared mutable, and only other const member functions can be called.

Why does a chaining mutator return T& rather than T?

Returning T& with return *this; hands the next call the same object, so every call in the chain modifies it. Returning T by value hands back a copy: the rest of the chain modifies temporaries and the original object is left unchanged, with no compiler error.

What are the only two differences between struct and class in C++?

Default member access — public in a struct, private in a class — and default inheritance, which is likewise public for a struct and private for a class. Everything else, including member functions and constructors, is identical.

Exercises

A chaining gradebook

Write class Student: a name, a private std::vector<int> of marks with the invariant that every stored mark is 0–100, and a private count of rejected marks. Student& add(int mark) stores a valid mark or counts an invalid one, and returns *this so calls chain. Const readers: name(), average() (0 when there are no marks), best() (the highest mark) and rejected(). Use explicit on the constructor.

Read n students, each as name k m1 ... mk. Print <name> avg <average to two decimals> best <best or none> rejected <count> per student, then top <name> for the highest average (the first one on a tie).

Input: n (at least 1), then n lines. Output: n + 1 lines.

3
ada 3 90 80 101
bob 2 70 -5
cy 0

→

ada avg 85.00 best 90 rejected 1
bob avg 70.00 best 70 rejected 1
cy avg 0.00 best none rejected 0
top ada

A grid with const and non-const at()

Write class Grid over a row-major std::vector<int> with rows(), cols(), and two overloads of at(r, c): int& at(int, int) for writing and const int& at(int, int) const for reading, both throwing std::out_of_range for a bad cell. Two mutators return Grid& so they chain: flipRows() reverses the order of the rows and flipCols() reverses every row; a half-turn of the grid is the one chain g.flipRows().flipCols(). long long sum() const totals the cells. The free function show(const Grid&) prints the rows, space-separated, through the const at.

Read R C, the grid, then q commands: set r c v (writes through the non-const at; prints nothing), get r c (reads through a const Grid&; prints the value), turn (the chain; prints nothing), show, sum. A set or get on a bad cell prints out of range.

Input: R C, R rows of C integers, q, then q commands. Output: the lines the commands produce.

2 3
1 2 3
4 5 6
5
get 1 2
turn
show
set 0 0 9
get 0 0

→

6
6 5 4
3 2 1
9

Assembly line, traced

Part prints make <name> when constructed and scrap <name> when destroyed. Write class Widget with three Part members declared in the order frame_, motor_, shell_, an int serial_, and an inline static int built_ counting every widget assembled. The constructor takes a model name, initialises the parts as <model>-frame, <model>-motor, <model>-shell and the serial as ++built_ — all in the member-initialiser list — then prints assembled #<serial> <model>. The destructor prints disassemble #<serial>; the parts are then scrapped in reverse order by the language. Delete copying, so the count cannot drift, and publish the count through static int built().

Commands, each in its own block followed by --: one <model> builds one widget; two <a> <b> builds a then b in the same block. Finish with built <count>. Trace it on paper first: the checkpoint says so.

Input: n, then n commands. Output: the trace, then the count.

1
two b c

→

make b-frame
make b-motor
make b-shell
assembled #1 b
make c-frame
make c-motor
make c-shell
assembled #2 c
disassemble #2
scrap c-shell
scrap c-motor
scrap c-frame
disassemble #1
scrap b-shell
scrap b-motor
scrap b-frame
--
built 2

In this module: Classes and objects

← Designing a class — headers, sources and a worked design · Copy semantics — what a copy is, and when the default one is wrong →