Last Updated: January 3, 2026
29 quizzes
Which statement best describes runtime polymorphism in C++?
Which of the following is required to achieve runtime polymorphism?
What happens if a derived class does NOT override a virtual function from the base class?
What is a correct reason to use a pure virtual function?
Which class is abstract?
Why should a polymorphic base class usually have a virtual destructor?
Which is true about RTTI (Runtime Type Information) in C++?
What does dynamic_cast do when downcasting a pointer and the cast is invalid?
Which declaration correctly defines a pure virtual function?
How does using virtual functions typically affect performance?
Which cast should you prefer for safe polymorphic downcasting?
Declare a virtual function to enable polymorphic drawing of widgets
class Widget {public: void draw() const;};Click an option to fill the blank:
Declare a pure virtual function for computing the area of a shape
class Shape {public: virtual double area() const ;};Click an option to fill the blank:
Use dynamic_cast to safely downcast a base pointer to Derived*
Derived* d = <Derived*>(basePtr);Click an option to fill the blank:
What is the output of this code?
1#include <iostream>
2
3class Base {
4public:
5 virtual void f() const { std::cout << "Base::f\n"; }
6};
7
8class Derived : public Base {
9public:
10 void f() const override { std::cout << "Derived::f\n"; }
11};
12
13int main() {
14 Derived d;
15 Base* b = &d;
16 b->f();
17 return 0;
18}What is the output of this code using an abstract base pointer?
1#include <iostream>
2
3class Shape {
4public:
5 virtual void draw() const = 0;
6 virtual ~Shape() { std::cout << "Shape dtor\n"; }
7};
8
9class Circle : public Shape {
10public:
11 void draw() const override { std::cout << "Circle::draw\n"; }
12 ~Circle() { std::cout << "Circle dtor\n"; }
13};
14
15int main() {
16 Shape* s = new Circle();
17 s->draw();
18 delete s;
19 return 0;
20}What is the output when calling a non-overridden virtual function?
1#include <iostream>
2
3class Logger {
4public:
5 virtual void info() const { std::cout << "Logger::info\n"; }
6 virtual void error() const { std::cout << "Logger::error\n"; }
7};
8
9class FileLogger : public Logger {
10public:
11 void error() const override { std::cout << "FileLogger::error\n"; }
12};
13
14int main() {
15 FileLogger fl;
16 Logger& ref = fl;
17 ref.info();
18 ref.error();
19 return 0;
20}What is the output of this RTTI example?
1#include <iostream>
2#include <typeinfo>
3
4class Base {
5public:
6 virtual ~Base() {}
7};
8
9class Derived : public Base {};
10
11int main() {
12 Base* b1 = new Base;
13 Base* b2 = new Derived;
14
15 std::cout << std::boolalpha;
16 std::cout << (dynamic_cast<Derived*>(b1) != nullptr) << "\n";
17 std::cout << (dynamic_cast<Derived*>(b2) != nullptr) << "\n";
18
19 delete b1;
20 delete b2;
21 return 0;
22}What is the output when slicing occurs but calling through a reference?
1#include <iostream>
2
3class Animal {
4public:
5 virtual void speak() const { std::cout << "Animal\n"; }
6};
7
8class Dog : public Animal {
9public:
10 void speak() const override { std::cout << "Dog\n"; }
11};
12
13void makeSpeak(Animal a) {
14 a.speak();
15}
16
17int main() {
18 Dog d;
19 Animal& ref = d;
20 ref.speak();
21 makeSpeak(d);
22 return 0;
23}Find the bug related to polymorphic deletion
Click on the line(s) that contain the bug.
#include <iostream> class Base {public: Base() { std::cout << "Base ctor\n"; } ~Base() { std::cout << "Base dtor\n"; }}; class Derived : public Base {public: Derived() { std::cout << "Derived ctor\n"; } ~Derived() { std::cout << "Derived dtor\n"; }}; int main() { Base* b = new Derived(); delete b; return 0;}Find the bug in this RTTI-based downcast
Click on the line(s) that contain the bug.
#include <iostream> class Shape {public: void draw() const { std::cout << "Shape::draw\n"; }}; class Circle : public Shape {public: void draw() const { std::cout << "Circle::draw\n"; }}; int main() { Shape* s = new Circle(); Circle* c = dynamic_cast<Circle*>(s); if (c) c->draw(); delete s; return 0;}Click the line where dynamic dispatch actually occurs
Click on the line to select.
#include <memory>#include <iostream> class Command {public: virtual void execute() = 0; virtual ~Command() = default;}; class PrintCommand : public Command {public: void execute() override { std::cout << "Print\n"; }}; int main() { std::unique_ptr<Command> cmd = std::make_unique<PrintCommand>(); cmd->execute(); return 0;}Click the line that makes Shape an abstract class
Click on the line to select.
#include <iostream> class Shape {public: virtual void draw() const = 0; virtual ~Shape() = default;}; class Rectangle : public Shape {public: void draw() const override { std::cout << "Rectangle\n"; }}; int main() { // Shape s; // not allowed Rectangle r; r.draw(); return 0;}Complete the code to use dynamic_cast safely in an event handling system
class Event { public: virtual ~Event() = default; };class MouseEvent : public Event { };void handle(Event* e) { if (auto* m = <MouseEvent*>()) { // handle mouse event }}Click an option to fill blank 1:
Complete the interface to support cloning via polymorphism
class Shape {public: virtual ~Shape() = default; virtual Shape* () const = 0;};class Circle : public Shape {public: Circle* () const override { return new Circle(*this); }};Click an option to fill blank 1:
Match the polymorphism-related C++ keyword with its primary purpose
Click an item on the left, then click its match on the right. Click a matched item to unmatch.
Match the class kind with its polymorphism role
Click an item on the left, then click its match on the right. Click a matched item to unmatch.
Order the steps when calling a virtual function through a base pointer at runtime
Drag and drop to reorder, or use the arrows.
Order the steps to define and use an abstract base class for polymorphic drawing
Drag and drop to reorder, or use the arrows.