Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

📝 Knowledge Test

/
Knowledge Test Score Board
· 0%

Work through the questions below — your score updates as you go.

Keep going · grade bands mapped to DCU's honours scale

target15:00

Only your first attempt at each question counts toward this score. Reload the page to reset.

This section contains 20 interactive knowledge checks designed to test your understanding of the materials covered in Chapter 5. The questions cover class architecture, inheritance patterns, dynamic memory (heap vs stack), explicit casting, operator overloading, and separate compilation.

Please remember that many of the quizzes have multiple correct answers, and you must select all applicable options to succeed. I have carefully balanced the lengths of the answers, so take your time to evaluate each option thoroughly.

Good luck!

Derek.


Part 1: Classes, Constructors, and the Rule of Five

Section titled “Part 1: Classes, Constructors, and the Rule of Five”
Q1
Quiz
Select 0/1

Why is it considered essential to use Member Initialisation Lists when writing constructors in C++?

Because they allow the programmer to explicitly call base class constructors and initialise object members before the constructor body executes.
Because they are the only mechanism available in C++ to assign default values to static global variables.
Because if you do not use them, C++ automatically promotes all private member variables to public scope.
Because they bypass the compiler entirely, injecting values straight into the CPU cache for maximum performance.
Q2
Code Cloze
C++

Understanding Move Semantics (C++11)

Drag snippets from the pool into the blanks so the program produces the output shown, then click Submit.

1class Buffer {
2 int* data;
3public:
4 // Move Assignment Operator
5 Buffer& operator=(Buffer····· source) noexcept {
6 if (this != &source) {
7 delete[] data; // Free existing resource
8 data = source.data; // Steal pointer
9 source.data = ·····; // Leave source in a safe state
10 }
11 return ·····;
12 }
13};

Available Snippets

nullptr
&
0
*this
this
&&
null
Q3
Code Output
C++

Predict the output: Static Methods vs Instance Methods

Read the code below, then choose the terminal output it produces and click Submit.

1#include <iostream>
2class Counter {
3private:
4 static int globalCount;
5 int localCount;
6public:
7 Counter() : localCount(0) { globalCount++; }
8 void increment() { localCount++; globalCount++; }
9 static int getGlobal() { return globalCount; }
10 int getLocal() const { return localCount; }
11};
12
13int Counter::globalCount = 0;
14
15int main() {
16 Counter a, b;
17 a.increment();
18 b.increment();
19 b.increment();
20 std::cout << Counter::getGlobal() << " " << a.getLocal() << " " << b.getLocal();
21 return 0;
22}
stdout
2 1 2
stdout
5 1 2
stdout
4 1 2
stdout
5 2 3
Q4
Concept Match

Match the Rule of Five/Zero Concept

Drag each definition into its matching concept slot, then click Submit. Tap × to return a placed card to the pool.

Rule of Zero
drag a definition here…
Move Constructor
drag a definition here…
Copy Assignment
drag a definition here…
Deep Copy
drag a definition here…

Definition Pool

Designing classes to use smart pointers and standard containers so you don't need to write any custom memory management methods.
Allocating entirely new memory blocks and duplicating the actual data, rather than just copying pointer addresses.
An operator (operator=) that safely duplicates data from an existing object into an already constructed object.
A method that takes an rvalue reference to efficiently 'steal' resources from a temporary source object.
Q5
Quiz
Select 0/1

In C++, what is the primary distinction between a 'struct' and a 'class'?

Structs cannot participate in inheritance hierarchies or utilize virtual functions.
A struct is purely a data container and cannot have member methods, whereas a class encapsulates both data and methods.
A struct defaults to public access for its members and base classes, whereas a class defaults to private access.
Structs are allocated exclusively on the stack, while classes are always dynamically allocated on the heap.
Q6
Code Cloze
C++

Constructor Delegation (C++11)

Drag snippets from the pool into the blanks so the program produces the output shown, then click Submit.

1class Sensor {
2 int id;
3 int timeout;
4public:
5 // Main constructor
6 Sensor(int id, int timeout) : id(id), timeout(timeout) {}
7
8 // Delegating constructor
9 Sensor(int id) ····· ·····(id, 5000) {}
10};

Available Snippets

super
Sensor
this
::
base
:
Q7
Quiz
Select 0/1

If you allocate an object dynamically on the heap (e.g., Account* a = new Account()), what happens if you forget to call 'delete a' before the program ends?

The operating system immediately triggers a segmentation fault, terminating the process because of unfreed memory.
The C++ compiler will automatically insert a 'delete' command at the end of the main function to prevent leaks.
The object on the heap safely invokes its own virtual destructor precisely as the program is closing.
The pointer 'a' on the stack is destroyed when it goes out of scope, but the object on the heap remains, causing a memory leak.
Q8
Code Cloze
C++

Safe Array Allocation and Deallocation

Drag snippets from the pool into the blanks so the program produces the output shown, then click Submit.

1int main() {
2 // Dynamically allocate an array of 50 accounts
3 Account* fleet = ····· Account[50];
4
5 // Deallocate the array safely
6 ····· fleet;
7 return 0;
8}

Available Snippets

new
malloc
free
destroy()
delete
delete[]
Q9
Code Output
C++

Predict the output: Object Slicing

Read the code below, then choose the terminal output it produces and click Submit.

1#include <iostream>
2class Base {
3public:
4 virtual void print() const { std::cout << "Base "; }
5};
6
7class Derived : public Base {
8public:
9 void print() const override { std::cout << "Derived "; }
10};
11
12void showValue(Base b) { b.print(); }
13void showRef(const Base& b) { b.print(); }
14
15int main() {
16 Derived d;
17 showValue(d);
18 showRef(d);
19 return 0;
20}
stdout
Base Derived 
stdout
Derived Derived 
stdout
Base Base 
stdout
Derived Base 
Q10
Quiz
Select 0/1

Why does adding a single 'virtual' method to a C++ class increase the size of every instantiated object by 8 bytes (on a 64-bit system)?

Because the source code of the virtual method is injected directly into the object's memory footprint.
Because the compiler must generate a hidden 'vptr' (vtable pointer) at offset 0 of the object to locate the correct method implementations at runtime.
Because virtual methods automatically double the size of all integer types within the class to prevent arithmetic overflows.
Because the virtual keyword forces the object to be aligned to a 64-byte boundary, injecting massive amounts of padding.

Part 3: Inheritance, Polymorphism, and Casting

Section titled “Part 3: Inheritance, Polymorphism, and Casting”
Q11
Code Cloze
C++

Solving the Diamond Problem

Drag snippets from the pool into the blanks so the program produces the output shown, then click Submit.

1class Device {
2public:
3 virtual void powerOn() = 0;
4};
5
6// Virtually inherit from Device
7class Transmitter : ····· public Device {
8 // ...
9};
10
11// Virtually inherit from Device
12class Receiver : ····· public Device {
13 // ...
14};
15
16// Multiple inheritance
17class Transceiver : public Transmitter, public Receiver {
18 // ...
19};

Available Snippets

friend
static
virtual
override
virtual
final
Q12
Concept Match

Match the Explicit Cast

Drag each definition into its matching concept slot, then click Submit. Tap × to return a placed card to the pool.

static_cast
drag a definition here…
dynamic_cast
drag a definition here…
const_cast
drag a definition here…
reinterpret_cast
drag a definition here…

Definition Pool

Used specifically to add or remove 'const' qualifiers, though modifying a true constant results in undefined behaviour.
The most dangerous cast, performing simple bit-level reinterpretation between unrelated pointer types.
A type-safe downcast exclusively for polymorphic classes that performs a crucial run-time check.
The standard tool for safe, well-defined conversions verified at compile time (e.g., float to int).
Q13
Code Cloze
C++

Using dynamic_cast Safely

Drag snippets from the pool into the blanks so the program produces the output shown, then click Submit.

1void checkAccount(Account* acc) {
2 // Attempt a safe downcast
3 CurrentAccount* current = ·····<CurrentAccount*>(acc);
4
5 // Check if the cast succeeded
6 if (current != ·····) {
7 current->processOverdraft();
8 }
9}

Available Snippets

static_cast
dynamic_cast
nullptr
void
reinterpret_cast
NULL
Q14
Quiz
Select 0/2

Why is std::bit_cast (C++20) preferred over reinterpret_cast when inspecting the raw bit pattern of a floating-point number?

Because std::bit_cast automatically encrypts the bit pattern using AES-256 for secure transmission.
Because std::bit_cast copies the exact bit pattern safely and can be evaluated at compile time (constexpr).
Because using reinterpret_cast to read a float through an int pointer violates the 'strict aliasing' rule, resulting in Undefined Behaviour.
Because reinterpret_cast is restricted strictly to C-style strings and cannot be used on numeric variables.
Q15
Code Cloze
C++

The override and final Keywords

Drag snippets from the pool into the blanks so the program produces the output shown, then click Submit.

1class Base {
2public:
3 virtual void process() {}
4};
5
6class Derived : public Base {
7public:
8 // Ensure this correctly overrides a base method
9 void process() ····· ····· {}
10};
11
12class Terminal ····· : public Derived {
13 // Cannot inherit from Terminal
14};

Available Snippets

override
final
virtual
const
static
final
sealed
Q16
Quiz
Select 0/1

Why is std::variant (C++17) recommended over a raw 'union' in modern C++?

Because std::variant is compressed by the compiler, using half the memory footprint of a standard raw union.
Because raw unions are deprecated and will cause modern C++20 compilers to fail with a syntax error.
Because std::variant automatically manages type safety, throwing a std::bad_variant_access exception if you attempt to read the wrong active type.
Because std::variant allows multiple data members to be active and accessed simultaneously.

Part 4: Friend Functions, Overloading, and Separate Compilation

Section titled “Part 4: Friend Functions, Overloading, and Separate Compilation”
Q17
Quiz
Select 0/2

Which of the following are true regarding the C++ 'friend' keyword?

Friendship is highly contagious; if Class A is a friend of Class B, and Class B is a friend of Class C, then Class A is automatically a friend of Class C.
Friendship is automatically inherited, meaning any class that derives from a friend class also gains full access to private members.
Friendship is commonly used when overloading the stream insertion operator (operator<<) so it can access private data without needing public getters.
A friend function is not a member of the class, but it is explicitly granted access to the class's private and protected members.
Q18
Code Order
C++

Operator Overloading: Post-Increment

Drag the tiles to arrange the code in the correct order, then click Submit. Locked lines stay in place. Indentation is dynamically applied based on the location of braces.
Number Number::operator++(int) {
return temp;
Number temp = *this;
temp++;
}
Q19
Code Cloze
C++

Include Guards in Header Files

Drag snippets from the pool into the blanks so the program produces the output shown, then click Submit.

1// Prevent multiple definitions (ODR violations)
2#····· ROBOT_H
3#····· ROBOT_H
4
5class Robot {
6 // Class definitions
7};
8
9#·····

Available Snippets

undef
include
endif
pragma
ifdef
define
ifndef
Q20
Code Output
C++

Predict the output: Const Correctness

Read the code below, then choose the terminal output it produces and click Submit.

1#include <iostream>
2
3class Sensor {
4 int value;
5public:
6 Sensor(int v) : value(v) {}
7 void read() { std::cout << "M" << value << " "; value++; }
8 void read() const { std::cout << "C" << value << " "; }
9};
10
11int main() {
12 Sensor s1(10);
13 const Sensor s2(20);
14
15 s1.read();
16 s1.read();
17 s2.read();
18
19 return 0;
20}
stdout
M10 M11 C20 
stdout
C10 C11 C20 
stdout
M10 M10 C20 
stdout
M10 M11 M20 

Congratulations on completing the Chapter 5 Knowledge Test! Review any questions you missed to ensure a solid grasp of complex object-oriented design and memory management before advancing to the C++ Standard Library.