Compile time and run time polymorphism

Compile-time polymorphism is resolved by the compiler from the argument list (overloading, early binding); run-time polymorphism is resolved while the program runs through virtual functions (late binding).

9 min read · 10 cards · 2 checks

Read in: English · हिन्दी · ગુજરાતી


Theory

Two decisions, two clocks

Yesterday you saw the till behave two ways: bill(50) vs bill(50, 0.1) picked by the compiler, and p.discount() picked only when a real card tapped.

Same pillar, but the moment of decision is completely different: one choice is sealed before the program ever starts, the other stays open until the exact instant of the call.

Examiners adore this contrast: "Differentiate compile-time and run-time polymorphism" is close to a guaranteed question. Let us make the difference impossible to forget.

Theory

Printed menu vs daily special

The canteen's printed menu was fixed at the printing press: whatever you order from it, the kitchen's response was decided long ago. That is compile-time: decided before serving begins.

The daily special board is decided each morning by whoever runs the kitchen that day. Same board, different dish depending on the actual day. That is run-time: the answer exists only in the moment.

Theory

Binding: the word behind both

Binding means connecting a function call to the function body that will run.

  • Early (static) binding: the connection is fixed during compilation. The compiler reads bill(50, 0.1), matches the argument list to one overload, and hard-wires the call.
  • Late (dynamic) binding: the connection is made while the program runs. The call p.discount() is routed to whichever object p actually refers to, checked at that moment.

Compile-time polymorphism uses early binding; run-time polymorphism uses late binding.

At a glance

The exam table

AspectCompile-timeRun-time
Also calledStatic, early bindingDynamic, late binding
DecidedDuring compilationDuring execution
Achieved byFunction + operator overloadingVirtual functions + inheritance
Needs inheritance?NoYes, with base pointer/reference
SpeedFaster (call hard-wired)Slightly slower (looked up)
FlexibilityFixed at buildAdapts to the actual object

Practical

Both clocks in one program

#include <iostream>
using namespace std;

class Person {
public:
    virtual double discount() { return 0.0; }  // virtual: late binding
};
class Student : public Person {
public:
    double discount() { return 0.10; }         // overrides Person's
};

// COMPILE-TIME: two overloads, picked by argument list
double bill(double amt) { return amt; }
double bill(double amt, double disc) { return amt * (1 - disc); }

int main() {
    cout << bill(50.0) << endl;        // compiler chose overload 1
    cout << bill(50.0, 0.2) << endl;   // compiler chose overload 2

    Person *p = new Student();          // base pointer, derived object
    cout << p->discount() << endl;      // 0.10: decided AT RUN TIME
    delete p;
    return 0;
}

Think first

Remove one word, change the answer

In the code above, delete the word virtual from Person::discount(). Now what does p->discount() print, and why?

Show the answer

It prints 0, the Person version. Without virtual, the compiler binds the call early, by the pointer's type: p is a Person pointer, so Person::discount() is hard-wired, no matter what object actually lives there. One keyword is the entire difference between early and late binding, which is why exams love asking for output with and without virtual.

Quiz

Which statement about run-time polymorphism is TRUE?

  1. It requires inheritance and is achieved through virtual functions
  2. It is faster than compile-time polymorphism because decisions are fresher
  3. Function overloading is its most common example
  4. The compiler resolves it by checking argument types
Show the answer

It requires inheritance and is achieved through virtual functions

Run-time polymorphism exists only across an inheritance hierarchy, dispatched through virtual functions via base pointers/references. It is marginally slower (the program looks the target up at call time), not faster, so B is wrong. C and D describe compile-time polymorphism: overloading, resolved from the argument list during compilation. Swapping the two families is the classic lost mark here.

Watch out

Where answers lose marks

Three precision points examiners check:

  • Say "early/static binding" for compile-time and "late/dynamic binding" for run-time; the synonyms ARE the marks.
  • Overriding without virtual is NOT run-time polymorphism: the base pointer still calls the base version.
  • Templates also count as compile-time polymorphism; mention them only if your paper covers them, else stick to overloading.

Theory

The rule of thumb that always works

Ask one question: could the compiler already know? If the argument list decides (overloading), it could, so compile-time. If the answer depends on which object a pointer happens to hold while running, it could not, so run-time. The next lessons zoom into each family: overloading vs overriding first, then virtual functions themselves.

Summary

Key takeaways

  • Binding = linking a call to a function body; early binding at compilation, late binding at execution.
  • Compile-time polymorphism: function/operator overloading, resolved from the argument list, faster.
  • Run-time polymorphism: virtual functions + inheritance via base pointers/references, flexible.
  • Without the virtual keyword, the pointer's type decides: base version runs (early binding).
  • Run-time needs inheritance; compile-time does not.
  • Memory hook: printed menu vs daily special board.

Study this properly

This page is the lesson to read. In Gri-Learn the same topic is a graded deck: the self-checks are scored and your weak topics are tracked. Free to start.

Start this topic

Already have an account? Sign in

More from Polymorphism

Gri-Learn · syllabus-mapped B.C.A. lessons in English, Hindi and Gujarati

Compile time and run time polymorphism · Object Oriented Programming and Data Structures (OOPs & D.S.) · Gri-Learn