optional · CSS study notes
14. Pure-Virtual Functions
Declared with = 0, has no implementation in the base class — forces every derived class to provide its own implementation.
class Shape
{
public:
virtual double area() = 0; // pure virtual -- no body, no default behavior
};
// Shape s; // ERROR: cannot instantiate a class with a pure virtual function
class Circle : public Shape
{
double radius;
public:
Circle(double r) : radius(r) {}
double area() override { return 3.1416 * radius * radius; } // MUST implement, or Circle is abstract too
};
MCQ Trap: A pure virtual function (
= 0) has no base-class implementation and forces overriding; a plain virtual function has a default implementation that CAN be overridden but doesn't have to be.
Syntax and the compile-time enforcement
class Shape
{
public:
virtual double area() = 0; // pure virtual -- the "= 0" is what makes it pure
};
// Shape s; // COMPILE ERROR: cannot declare variable of abstract type 'Shape'
class Circle : public Shape
{
double radius;
public:
Circle(double r) : radius(r) {}
double area() override { return 3.1416 * radius * radius; } // MUST provide this, or Circle stays abstract too
};
int main()
{
Circle c(5);
cout << c.area(); // OK -- Circle is concrete, all pure virtuals implemented
Shape* s = new Circle(5); // OK -- pointer/reference to abstract class is fine
return 0;
}
What happens if a derived class does NOT implement it
class Square : public Shape {}; // area() NOT implemented
// Square sq; // COMPILE ERROR -- Square is STILL abstract, since it didn't implement area()
A pure virtual function's "pureness" is inherited down the chain until some class actually implements it — students often assume any subclass automatically becomes concrete, which is false.
Why use a pure virtual function instead of a regular one?
A regular virtual function has a default body, so a derived class may skip overriding it. A pure virtual function forces every concrete derived class to provide its own implementation — useful when there is no sensible default (e.g., Shape::area() — there's no meaningful "generic shape area").
Important MCQs
- A pure virtual function is declared with:
- a)
virtual void f();b)virtual void f() = 0;c)void f() {}d)static void f() = 0;
- a)
- A class with a pure virtual function that is NOT implemented by a derived class:
- a) Becomes concrete automatically b) Remains abstract in the derived class too c) Causes a runtime error only d) Is deleted by the compiler
- Why use a pure virtual function rather than a regular virtual function with a default body?
- a) It's faster b) There is no sensible default implementation, and every subclass must provide its own c) It uses less memory d) It's required by all classes
Self-Test Questions
- What does the
= 0syntax actually do to a virtual function? - If
Square : public Shapedoesn't implementarea(), can you create aSquareobject? Why or why not? - When would you choose a pure virtual function over a regular virtual function with a default body?
📌 Sample & Repeated FPSC Questions (2016–2026)
2025, Paper I, Q3(c) (8 marks) — Explain the role of pure virtual functions in implementing abstract classes in C++. How do they differ from virtual functions? Give an example of C++ classes where both types of functions are used.
A pure virtual function (virtual void draw() = 0;) has no default implementation in its declaring class; declaring even one makes that class abstract — it cannot be instantiated, and any concrete derived class must override every pure virtual function to become instantiable. Its role is to force a common interface/contract onto all derived classes.
An ordinary virtual function, by contrast, HAS a body in the base class; a derived class MAY override it, but the base version runs if it doesn't — the class stays instantiable either way.
class Shape {
public:
virtual double area() const = 0; // pure virtual: must be implemented
virtual void display() const { // ordinary virtual: has a default body
cout << "Area = " << area() << endl;
}
virtual ~Shape() {}
};
class Circle : public Shape {
double radius;
public:
Circle(double r) : radius(r) {}
double area() const override { return 3.1416 * radius * radius; }
// display() not overridden -> uses Shape's default, but still calls Circle::area() via polymorphism
};
Shape s; is a compile error (pure virtual area() unimplemented); Circle c(5); compiles fine. display() shows both kinds of virtual function coexisting in one class.
2018, Paper I, Q4(c) (5 marks) — Suppose class C contains a pure virtual function. Suppose we wish to instantiate objects of this hierarchy. Which class(es) are or could be abstract and which are concrete?
Given a hierarchy where A is the root, B and C derive from A, and C declares a pure virtual function that D and E derive from:
Cis abstract — it declares the pure virtual function without implementing it.DandEare abstract UNLESS each supplies its own concrete override of that function — "pure-ness" propagates down the hierarchy until some class actually implements it. (A common mistake: assuming any subclass automatically becomes concrete just by inheriting.)AandBare concrete — the pure virtual function is introduced inC, not inA, soAand its other childBhave no obligation tied to it.
MCQ Trap: a derived class that does NOT override an inherited pure virtual function remains abstract too, even if it overrides other, unrelated methods perfectly well.
📜 Past-Paper Questions & MCQs (CSS 2016–2026)
2018 · Paper-I · Q4(c) · 5 marks
Q. Suppose class C in the hierarchy A → B, A → C, C → D, C → E contains a pure virtual function. Which classes are or could be abstract and which are concrete?
Ans.
- C is abstract, because it has a pure virtual function and cannot be instantiated.
- D and E are concrete only if they override that pure virtual function. If one does not, it stays abstract too.
- A and B are unaffected, so they can be concrete (A is a base class and B is a sibling of C, so neither inherits the pure function).
2025 · Paper-I · Q3(c) · 8 marks
Q. Explain the role of pure virtual functions in implementing abstract classes in C++. How do they differ from virtual functions? Give an example where both are used.
Ans.
- A pure virtual function has no body in the base class and is declared with
= 0. A class containing one is abstract, so no objects can be created from it. It acts as an interface that every derived class must implement.
| Basis | Virtual function | Pure virtual function |
|---|---|---|
| Body in base class | Yes (default behaviour) | No (declared = 0) |
| Overriding in derived class | Optional | Mandatory (else the derived class stays abstract) |
| Base class objects | Allowed | Not allowed |
class Shape { // abstract class
public:
virtual double area() = 0; // pure virtual
virtual void describe() { cout << "I am a shape\n"; } // virtual with default body
virtual ~Shape() {}
};
class Circle : public Shape {
double r;
public:
Circle(double x) : r(x) {}
double area() override { return 3.14159 * r * r; } // must implement
};