Dashboard/Block 4: Advanced OOP/Week 10
Week 10Advanced OOP

Polymorphism

Okay, picture this: you've got an array of Shape* pointers, and each one is secretly pointing to a different shape — a Circle, a Rectangle, a Triangle. You loop through them and call shape->area() on every single one. Here's the cool part: the right version of area() runs for each shape, even though your pointer type is just Shape* for all of them. How does that work? Welcome to polymorphism — a Greek word that literally means "many forms." And honestly? It's probably the most powerful idea in all of object-oriented programming.

But how does C++ actually figure out which area() to call at runtime? Think of it like this: imagine every class carries a little cheat sheet — a hidden lookup table that says "when someone calls area() on me, here's the actual function to run." That cheat sheet is called a vtable (virtual table), and the whole process of checking it at runtime is called dynamic dispatch. The keyword that kicks all of this off? virtual. Without it in your base class, C++ just blindly calls the base version. With virtual, it checks the actual object and picks the right function. Pretty neat, right?

Now, what if the base class concept is too vague to even have a real implementation? Like, what's the area of a generic "shape"? That doesn't even make sense. So you mark the function as pure virtual with = 0 (like virtual double area() const = 0;), and now the class becomes abstract — you literally cannot create objects of it. It's basically a contract that says "any class inheriting from me MUST fill in these blanks." Oh, and one more critical thing you need to know: virtual destructors. If you delete a derived object through a base pointer without one, only the base class destructor runs — meaning your derived class's cleanup code never executes, and you've got yourself a resource leak.

ConceptWhat It MeansExample
Virtual functionA function that uses dynamic dispatch to call the correct derived version at runtimevirtual double area() const;
Pure virtual functionA function with no implementation in the base class — derived classes MUST override itvirtual double area() const = 0;
Abstract classA class with at least one pure virtual function — cannot be instantiatedShape with area() = 0
Dynamic dispatchThe runtime mechanism that looks up the vtable to call the correct functionshape_ptr->area() calls Circle's or Rect's version
Virtual destructorEnsures the derived class destructor runs when deleting through a base pointervirtual ~Shape() {}

So why does all of this matter? Because polymorphism lets you write code that works with Shape* pointers, and it'll automatically handle any shape type — even ones that haven't been created yet. You're essentially coding against an interface, not a specific implementation, and that's a massive deal in real-world software.

Learning Objectives

Understand compile-time vs runtime polymorphism
Use virtual functions for dynamic dispatch
Create abstract classes with pure virtual functions
Use base class pointers to hold derived objects
Understand why virtual destructors are needed

Key Concepts

Polymorphism and Virtual Functions