Tutorials Logic, IN info@tutorialslogic.com

C++ Polymorphism: Overloads, Virtual Dispatch, and Slicing

Virtual Dispatch

Runtime polymorphism calls an overridden virtual function through a base reference or pointer. It supports substitutable implementations, but only when the base contract defines valid inputs, results, ownership, and destruction. The override keyword asks the compiler to verify that a derived method truly overrides.

Runtime Dispatch Needs a Reference or Pointer

A base value contains only the base subobject. Passing a derived object by value slices it, so virtual calls made on the copy cannot recover the discarded derived state.

Render heterogeneous notifications

Render heterogeneous notifications
#include <iostream>
#include <memory>
#include <vector>

struct Notice { virtual ~Notice() = default; virtual void send() const = 0; };
struct Email : Notice { void send() const override { std::cout << "email\n"; } };
struct Sms : Notice { void send() const override { std::cout << "sms\n"; } };

int main() {
    std::vector<std::unique_ptr<Notice>> notices;
    notices.push_back(std::make_unique<Email>());
    notices.push_back(std::make_unique<Sms>());
    for (const auto& notice : notices) notice->send();
}
Output
email
sms

Overload Hiding

A derived declaration with the same function name can hide all base overloads. Bring the base set into scope with using Base::name when that is the intended interface.

  • Use override to catch signature mismatches.
  • Give polymorphic bases a correct destructor policy.
  • Avoid downcasts when the interface can express the operation.

Object Lifetime

A polymorphic base normally needs a virtual destructor so deleting through a base pointer destroys the complete derived object. Store owning polymorphic objects in std::unique_ptr<Base> by default; use shared ownership only when the lifetime really has multiple independent owners.

Avoid calling virtual functions from constructors and destructors as a customization mechanism: dispatch is limited to the part currently being constructed or destroyed. Prevent slicing by passing polymorphic objects through references or pointers instead of copying them into base values.

Destroy Through the Base Interface

A virtual destructor preserves derived cleanup when an object is owned through a base pointer.

Destroy Through the Base Interface
#include <iostream>
#include <memory>

struct Task {
    virtual ~Task() = default;
    virtual void run() const = 0;
};
struct EmailTask final : Task {
    void run() const override { std::cout << "email\n"; }
};
int main() {
    std::unique_ptr<Task> task = std::make_unique<EmailTask>();
    task->run();
}
Output
email
  • Pass polymorphic objects by reference or pointer to avoid object slicing.
Before you move on

Dispatch Review

5 checks
  • Static and dynamic selection are distinguished.
  • No polymorphic object is passed by value.
  • Overrides are marked.
  • Ownership of heterogeneous objects is explicit.
  • The base interface contains required behavior.

Runtime Polymorphism Boundary

  • Object slicing

    Passing a derived object by value as its base removes the derived portion. Use a reference or smart pointer when dynamic behavior must be preserved.

Try this next

Polymorphism Practice

0 of 2 completed

  1. Pass a derived object to one function by base value and another by base reference, then compare which virtual behavior and derived state remain visible. The by-value parameter creates a new base object.
  2. Implement two concrete shapes behind a common interface and verify the same area-calculation loop works without subtype checks. A caller using the abstraction should not need dynamic_cast.

Polymorphism Questions

It occurs when a virtual function is called through a base reference or pointer. Direct calls on a known object do not need runtime dispatch.

No. The compiler chooses an overload from the argument types; virtual overriding is selected at runtime.

Copying a derived object into a base object discards the derived portion. Use references or smart pointers for polymorphic objects.

Next Step
Next Practice

Finish the concept here, then reinforce it with hands-on coding, interview prep, or a tool that matches the topic.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.