CSS Prepare

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

  1. A pure virtual function is declared with:
    • a) virtual void f(); b) virtual void f() = 0; c) void f() {} d) static void f() = 0;
  2. 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
  3. 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

  1. What does the = 0 syntax actually do to a virtual function?
  2. If Square : public Shape doesn't implement area(), can you create a Square object? Why or why not?
  3. 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:

  • C is abstract — it declares the pure virtual function without implementing it.
  • D and E are 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.)
  • A and B are concrete — the pure virtual function is introduced in C, not in A, so A and its other child B have 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.
BasisVirtual functionPure virtual function
Body in base classYes (default behaviour)No (declared = 0)
Overriding in derived classOptionalMandatory (else the derived class stays abstract)
Base class objectsAllowedNot 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
};