MockExams

Virtual Functions, Pure Virtual Functions, Abstract Classes & vptr/vtable

AI draft, not yet reviewedUnit 8: Virtual Functions and PolymorphismAbout 2 minutes

Idea in plain words

Upcasting: Base class pointer can point to a derived class object.

Exam tip

High-yield exam topic (Very High).

Explanation

Runtime polymorphism decouples system architectures from concrete implementations. The compiler achieves dynamic dispatch via vptr indexing into the class vtable at runtime (costing one pointer indirection). Virtual destructors are essential in C++ whenever a class contains any virtual functions.

Key points

  • Static Binding (Compile-time): Invokes base function based on pointer type; Dynamic Binding (Runtime): Invokes derived override based on pointed-to object.
  • Virtual Functions: Declared with virtual keyword in base class, resolved dynamically at runtime.
  • vtable & vptr: The compiler creates a Virtual Method Table (vtable) storing function pointers for each class with virtual functions, and injects a hidden pointer (vptr) into each object instance.
  • Pure Virtual Function (virtual void draw() = 0): Makes the class Abstract. Cannot instantiate abstract classes.
  • Virtual Destructor: Guarantees derived class destructors run when deleting derived objects through base class pointers, preventing memory leaks.

Example

Example

Without virtual destructor: 'delete s' where s is Shape* pointing to Circle would only execute ~Shape(), leaking Circle's internal resources.

Code examples

// Runtime Polymorphism & Virtual Destructors in C++
#include <iostream>
using namespace std;

class Shape {
public:
    virtual void draw() const = 0; // Pure virtual function => Abstract Class
    virtual double area() const = 0;

    virtual ~Shape() { // Crucial Virtual Destructor!
        cout << "Shape destroyed\n";
    }
};

class Circle : public Shape {
private:
    double radius;
public:
    Circle(double r) : radius(r) {}
    void draw() const override { cout << "Drawing Circle\n"; }
    double area() const override { return 3.14159 * radius * radius; }
    ~Circle() override { cout << "Circle destroyed\n"; }
};

int main() {
    Shape *s = new Circle(5.0); // Upcasting
    s->draw();                  // Dynamic dispatch via vtable!
    cout << "Area: " << s->area() << endl;
    delete s;                   // Calls ~Circle() then ~Shape() safely
    return 0;
}

Exam questions

  • [8 Marks] Explain the internal working mechanism of virtual functions using vtable (Virtual Table) and vptr (Virtual Pointer) diagrams.
  • [7 Marks] What is an abstract class and pure virtual function? Why is a virtual destructor necessary when dealing with inheritance?
  • [7 Marks] Compare compile-time polymorphism with run-time polymorphism with clear code demonstrations.

BIT154CO

Switch Course

On this page

Past Exam Questions

Not asked in past exams yet

This topic hasn't appeared in previous exam papers.

Search BIT154CO

Reading

Theme
Reading mode
Text size
Default
Font
Line width
Line spacing