How unit 4 is examined
Polymorphism, its two kinds, and how C++ achieves them by overloading (compile time) and virtual overriding (run time); the two comparison tables and the overloading programs carry the marks.
Polymorphism: Introduction
<span style="display:inline-block;padding:.16em .6em;border:1.5px solid currentColor;border-radius:999px;font-size:.68em;font-weight:700;letter-spacing:.06em;text-transform:uppercase;opacity:.75">Medium weight</span>
Definition. <mark>Polymorphism means "many forms": the ability of one name, message or operator to behave differently depending on the object or arguments it is used with.</mark>
Key points.
- Polymorphism is one of the four pillars of OOP, and it lets one interface be used for a general class of actions.
- It is of two types: compile-time (static, early binding) and run-time (dynamic, late binding).
- Compile-time polymorphism is implemented in C++ by function overloading, operator overloading and templates; the compiler picks the function.
- Run-time polymorphism is implemented by virtual functions and overriding through a base-class pointer or reference; the choice is made while the program runs.
- Significance: a uniform interface works for entities of different types, so
p->draw()works for a circle, a square or any future shape. - Reusability: generic code is written once against the base type and reused for every derived class.
- Flexibility: a new derived class can be added without changing existing code, so the program is easy to extend and maintain.
| Basis | Function overloading | Function overriding |
|---|---|---|
| Scope | Same class | Base and derived class |
| Signature | Must differ | Must be identical |
| Binding | Compile time | Run time (virtual) |
| Syntax | int f(int); int f(float); |
virtual void f(); in base, void f(); in derived |
Answer frame. Open with the definition and the two types; then list the C++ ways (overloading, operator overloading, virtual functions) with a two-line syntax snippet each; draw the table above for the difference question; close with significance: one interface, reusability, extensibility. For the significance question, develop points 5-7 with the shape example.
Asked: [7 marks] (Jun 2020, Jun 2023) Discuss Polymorphism in detail. What are the different ways to implement Polymorphism in C++? Give differences between function overloading and function overriding by writing its syntax. Asked: [7 marks] (Dec 2024) What is polymorphism in OOP? Discuss its significance and how it contributes to code reusability and flexibility.
Method Overriding & Overloading
<span style="display:inline-block;padding:.16em .6em;border:1.5px solid currentColor;border-radius:999px;font-size:.68em;font-weight:700;letter-spacing:.06em;text-transform:uppercase;opacity:.75">High weight</span>
Definition. <mark>Overloading is using the same function name in the same scope with different parameter lists; overriding is redefining a base-class virtual function in a derived class with the identical signature.</mark>
Key points.
- Overloaded functions must differ in the number, type or order of parameters; the return type alone is not enough.
- The compiler resolves overloads at compile time, so it is static polymorphism with no inheritance needed.
- Overriding needs inheritance: the derived function has the same name, parameters and return type as the base function.
- With
virtualin the base class, the call through a base pointer runs the derived version at run time. - Function polymorphism means one function name serving several purposes, that is, overloading.
- Operator overloading gives an existing operator a new meaning for user-defined types; it is necessary so that
a + bworks on objects like complex numbers or strings. - Cannot be overloaded:
::,.,.*,?:,sizeof. At least one operand must be a user-defined type. - Constructors can be overloaded too; the argument list decides which one runs.
| Basis | Overloading | Overriding |
|---|---|---|
| Scope | Same class | Base and derived class |
| Signature | Different | Same |
| Binding | Compile time | Run time |
| Inheritance | Not needed | Required |
| Keyword | None | virtual in base |
| Basis | Virtual function | Pure virtual function |
| --- | --- | --- |
| Body | Has a definition | Declared = 0, no body |
| Base class | Can be instantiated | Becomes abstract |
| Derived class | May override | Must override |
| Basis | Generalization | Specialization |
| --- | --- | --- |
| Direction | Bottom-up, extract common features | Top-down, add special sub-entities |
| Basis | Encapsulation | Inheritance |
| --- | --- | --- |
| Purpose | Binds data and functions, hides data | Acquires base-class properties for reuse |
Example.
class A { public: virtual void show() { cout << "A"; } void f(int x) {} void f(float y) {} }; // f overloaded
class B : public A { public: void show() { cout << "B"; } }; // show overridden
// A *p = new B; p->show(); prints B
class Complex {
float re, im;
public:
Complex(float r = 0, float i = 0) { re = r; im = i; }
Complex operator+(Complex c) { return Complex(re + c.re, im + c.im); }
void show() { cout << re << " + " << im << "i\n"; }
};
int main() { Complex a(2, 3), b(4, 5); (a + b).show(); } // 6 + 8i
int maxi(int a, int b) { return a > b ? a : b; }
int maxi(int a, int b, int c) { return maxi(maxi(a, b), c); }
int main() { int x, y, z; cin >> x >> y >> z; cout << maxi(x, y, z); } // 4 9 7 gives 9
class Shape {
float area;
public:
Shape(float r) { area = 3.14159f * r * r; } // circle
Shape(float l, float b) { area = l * b; } // rectangle
Shape(int s) { area = s * s; } // square
void show() { cout << "Area = " << area << endl; }
};
// main: read r, l, b, s with cin; Shape c(r), rect(l, b), sq(s); call show() on each
// input 3 4 5 6 gives 28.2743, 20, 36
The same idea gives the "area by method overloading" program: area(float r) for a circle and area(float l, float b) for a rectangle, chosen by the argument count, with input through cin.
Answer frame. For overloading vs overriding: open with both definitions, draw the table, show the two-line example above, close with "overloading is compile-time, overriding is run-time". For programs: state the principle in one line, declare the class, overload, write main() with cin/cout. For the 14-mark set: one table per pair, three rows each.
Pitfall: Overriding without
virtual(or with a different signature) hides the base function; the base version runs through a base pointer.
Asked: [14 marks] (Nov 2018) Explain: i) Overriding ii) Function Polymorphism Asked: [14 marks] (Dec 2023) Differentiate: a) Virtual and Pure virtual function b) Generalization and Specialization c) Encapsulation and Inheritance d) Function overloading and Function overriding Asked: [7 marks] (Nov 2019) Explain method overloading and method overriding with example. Asked: [7 marks] (Nov 2022, Dec 2025) Explain method overloading and method overriding with example; explain polymorphism with method overloading and overriding. Asked: [7 marks] (Dec 2020) Differentiate between method overriding and overloading. Asked: [7 marks] (Nov 2019) Write C++ program to overload '+' operator using member function to add two complex numbers. Asked: [7 marks] (May 2019) What is operator overloading? Why is it necessary to overload an operator? Asked: [7 marks] (Jun 2020) Write a C++ program to calculate the area of rectangle, square and circle using constructor overloading with user input. Asked: [7 marks] (Dec 2023) Using function overloading write a C++ program to find the maximum of three integers. Asked: [7 marks] (Jun 2023) Write a C++ program to calculate the area using method overloading that accepts input from the user and shows the result.
static and run time Polymorphism
<span style="display:inline-block;padding:.16em .6em;border:1.5px solid currentColor;border-radius:999px;font-size:.68em;font-weight:700;letter-spacing:.06em;text-transform:uppercase;opacity:.75">High weight</span>
Definition. <mark>Static (compile-time) polymorphism binds the function call to its code at compile time, whereas run-time polymorphism binds it while the program runs, through virtual functions and a base-class pointer.</mark>
Diagram. <figure class="ds-fig" style="margin:1.4rem 0;overflow-x:auto"><svg xmlns="http://www.w3.org/2000/svg" id="dsfig-u4-01" viewBox="0 0 424 252" width="424" height="252" role="img" aria-label="P = Polymorphism, CT = compile time (static), RT = run time (dynamic), O = overloading and templates, V = virtual functions"><style>#dsfig-u4-01 .e{stroke:#454C5A;stroke-width:1.4;fill:none}#dsfig-u4-01 .e.hi{stroke:#2340B8;stroke-width:2.6}#dsfig-u4-01 .n{fill:#FFFFFF;stroke:#16181D;stroke-width:1.4}#dsfig-u4-01 .n.hi{fill:#E3E9FC;stroke:#2340B8;stroke-width:2.2}#dsfig-u4-01 .n.rb-b{fill:#16181D;stroke:#16181D}#dsfig-u4-01 .n.rb-r{fill:#BD3227;stroke:#BD3227}#dsfig-u4-01 text{font-family:"JetBrains Mono",ui-monospace,Menlo,Consolas,monospace;font-size:13px}#dsfig-u4-01 .t{fill:#16181D;font-weight:500}#dsfig-u4-01 .t.inv{fill:#FFFFFF;font-weight:700}#dsfig-u4-01 .kd{stroke:#16181D;stroke-width:1.2}#dsfig-u4-01 .dot{fill:#16181D}#dsfig-u4-01 .ann{fill:#2340B8;font-size:11px;font-weight:700}#dsfig-u4-01 .lbl{fill:#6F7787;font-family:system-ui,-apple-system,sans-serif;font-size:12px;font-weight:700}#dsfig-u4-01 .ptr{fill:#2340B8;font-size:12px;font-weight:700}#dsfig-u4-01 .ah{fill:#454C5A}#dsfig-u4-01 .ah.hi{fill:#2340B8}#dsfig-u4-01 .wl rect{fill:#FFFFFF;stroke:#DCE0E7}#dsfig-u4-01 .wl .t{font-size:12px;font-weight:700}#dsfig-u4-01 .wl.hi rect{fill:#2340B8;stroke:#2340B8}#dsfig-u4-01 .wl.hi .t{fill:#FFFFFF}html.dark #dsfig-u4-01 .e{stroke:#B1B7C3}html.dark #dsfig-u4-01 .e.hi{stroke:#8FA3FF}html.dark #dsfig-u4-01 .n{fill:#161920;stroke:#E6E8ED}html.dark #dsfig-u4-01 .n.hi{fill:#1E2748;stroke:#8FA3FF}html.dark #dsfig-u4-01 .n.rb-b{fill:#E6E8ED;stroke:#E6E8ED}html.dark #dsfig-u4-01 .n.rb-r{fill:#FF7E71;stroke:#FF7E71}html.dark #dsfig-u4-01 .t{fill:#E6E8ED}html.dark #dsfig-u4-01 .t.inv{fill:#0F1115}html.dark #dsfig-u4-01 .kd{stroke:#E6E8ED}html.dark #dsfig-u4-01 .dot{fill:#E6E8ED}html.dark #dsfig-u4-01 .ann{fill:#8FA3FF}html.dark #dsfig-u4-01 .lbl{fill:#858D9C}html.dark #dsfig-u4-01 .ptr{fill:#8FA3FF}html.dark #dsfig-u4-01 .ah{fill:#B1B7C3}html.dark #dsfig-u4-01 .ah.hi{fill:#8FA3FF}html.dark #dsfig-u4-01 .wl rect{fill:#161920;stroke:#2A2E37}html.dark #dsfig-u4-01 .wl.hi rect{fill:#8FA3FF;stroke:#8FA3FF}html.dark #dsfig-u4-01 .wl.hi .t{fill:#0F1115}</style><defs><marker id="ah10" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path class="ah" d="M0,1 L9,5 L0,9 z"/></marker><marker id="ahh10" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path class="ah hi" d="M0,1 L9,5 L0,9 z"/></marker></defs><path class="e" d="M57,117.5 L193.2,49.4" marker-end="url(#ah10)"/><path class="e" d="M57,134.5 L193.2,202.6" marker-end="url(#ah10)"/><path class="e" d="M231,40 L363,40" marker-end="url(#ah10)"/><path class="e" d="M231,212 L363,212" marker-end="url(#ah10)"/><circle class="n" cx="40" cy="126" r="18"/><text class="t" x="40" y="126" dy=".35em" text-anchor="middle">P</text><circle class="n" cx="212" cy="40" r="18"/><text class="t" x="212" y="40" dy=".35em" text-anchor="middle">CT</text><circle class="n" cx="212" cy="212" r="18"/><text class="t" x="212" y="212" dy=".35em" text-anchor="middle">RT</text><circle class="n" cx="384" cy="40" r="18"/><text class="t" x="384" y="40" dy=".35em" text-anchor="middle">O</text><circle class="n" cx="384" cy="212" r="18"/><text class="t" x="384" y="212" dy=".35em" text-anchor="middle">V</text></svg><figcaption style="font-size:.82em;opacity:.72;margin-top:.45rem">P = Polymorphism, CT = compile time (static), RT = run time (dynamic), O = overloading and templates, V = virtual functions</figcaption></figure>
Key points.
- In compile-time polymorphism the compiler chooses the function from the call's arguments; this is early (static) binding.
- It is achieved by function overloading, operator overloading and templates, and it is fast because there is no lookup at run time.
- In run-time polymorphism the function is chosen by the actual object type, which is late (dynamic) binding.
- A virtual function is a base-class member declared with
virtual, which a derived class redefines with the same signature. - Dynamic dispatch works through the vtable: each class with virtual functions has a table of function addresses, and each object holds a hidden vptr to it; the call looks up the entry through the vptr.
- A base pointer or reference must be used; calling by object name does not give run-time behaviour.
- Make the base destructor virtual so that deleting through a base pointer destroys the derived part.
- A pure virtual function (
= 0) makes the class abstract, forcing derived classes to override.
class Shape { public: virtual void draw() { cout << "Shape\n"; } };
class Circle : public Shape { public: void draw() { cout << "Circle\n"; } };
class Square : public Shape { public: void draw() { cout << "Square\n"; } };
int main() { Circle c; Square q; Shape *p;
p = &c; p->draw(); // Circle
p = &q; p->draw(); } // Square
| Basis | Compile-time | Run-time |
|---|---|---|
| Binding | Early, static | Late, dynamic |
| Mechanism | Overloading, templates | Virtual functions, overriding |
| Decided by | Arguments | Object type |
| Speed | Faster | Slower (vtable lookup) |
| Flexibility | Less | More |
| Inheritance | Not needed | Required |
Example (Distance). Operator overloading, converting to millimetres and back so carries are automatic:
class Distance { int m, cm, mm;
static Distance make(int t) { Distance d; d.m = t / 1000; d.cm = t % 1000 / 10; d.mm = t % 10; return d; }
int total() { return m * 1000 + cm * 10 + mm; }
public: Distance(int a = 0, int b = 0, int c = 0) { m = a; cm = b; mm = c; }
Distance operator+(Distance d) { return make(total() + d.total()); }
Distance operator-(Distance d) { return make(total() - d.total()); } };
// (5m 60cm 8mm) + (2m 45cm 7mm) = 8 m 6 cm 5 mm; minus gives 3 m 15 cm 1 mm
Answer frame. Open with the definition of polymorphism ("many forms") and its two types; draw the tree; develop static then dynamic, each with its example; give the table; close with "static gives speed, dynamic gives flexibility". For "virtual functions": define, show the shape program with its output, explain the vptr and vtable.
Asked: [7 marks] (Nov 2022, Dec 2023, Dec 2024, Dec 2025) Define polymorphism and its types. How does compile-time polymorphism differ from run-time polymorphism? (compare and contrast with examples) Asked: [7 marks] (May 2019) Discuss and compare run time and compile time polymorphism. Asked: [7 marks] (Nov 2018) What is Run Time Polymorphism? Explain with example. Asked: [7 marks] (Nov 2019) Explain the meaning of polymorphism. How is polymorphism achieved at run time? Explain with an example. Asked: [7 marks] (May 2019) What are virtual functions? Explain with suitable program. Asked: [7 marks] (Dec 2020) How is polymorphism achieved at compile time and run time? Asked: [7 marks] (Nov 2022) What is operator overloading? Design a Distance class (meters, centimeters, millimeters) and overload addition and subtraction operators.
Last-minute revision
- Polymorphism means "many forms"; two types: compile-time (static) and run-time (dynamic).
- Overloading: same name, same scope, different signature, resolved at compile time.
- Overriding: same signature in the derived class, needs
virtualand a base pointer, resolved at run time. - Compile-time is early binding; run-time is late binding through the vptr and vtable.
- Return type alone cannot distinguish overloaded functions.
- Operators that cannot be overloaded:
::,.,.*,?:,sizeof. - Pure virtual function:
virtual void f() = 0;makes the class abstract. - Make the base destructor virtual when deleting through a base pointer.
- Function polymorphism is another name for function overloading.
- Distance program: convert to millimetres, add or subtract, convert back.
Memory hooks
- Overload = same class, Override = other class (derived).
- Early = compile = overload; Late = run = virtual.
- vptr points to the vtable; the vtable holds the function addresses.
- "One interface, many methods" is the one-line significance.
Coverage checklist
- Polymorphism: Introduction: definition, types, C++ ways, significance, overloading vs overriding (Jun 2020, Jun 2023, Dec 2024).
- Method Overriding & Overloading: overriding, function polymorphism, four differentiations, operator overloading, complex +, constructor overloading area, max of three, area by overloading (Nov 2018, May 2019, Nov 2019, Jun 2020, Dec 2020, Nov 2022, Jun 2023, Dec 2023, Dec 2025).
- static and run time Polymorphism: run-time polymorphism, virtual functions, compile vs run-time comparison, Distance operator overloading (Nov 2018, May 2019, Nov 2019, Dec 2020, Nov 2022, Dec 2023, Dec 2024, Dec 2025).