OOP Concepts in C++ for GATE CS – Classes, Inheritance, Polymorphism | EngineeringHulk


OOP Concepts in C++ for GATE CS

Classes, inheritance, polymorphism, virtual functions, abstract classes — all OOP in C++ tested in GATE with output-prediction examples.

Last updated: April 2026  |  GATE CS 2024–2026 syllabus

Key Takeaways for GATE

  • Encapsulation: data + methods in one class. private members inaccessible outside.
  • Constructor order: Base → Derived. Destructor order: Derived → Base (reverse).
  • Virtual function: runtime dispatch via vtable. virtual keyword in base. Overriding in derived.
  • Pure virtual (= 0): makes class abstract. Cannot instantiate abstract class.
  • Polymorphism via base pointer: Base *p = new Derived; p->vfunc(); calls Derived’s version.
  • Destructor must be virtual in base class to avoid memory leaks when deleting via base pointer.
  • Diamond problem: Use virtual base class to share single copy in multiple inheritance.

1. Four Pillars of OOP

PillarDefinitionC++ Mechanism
EncapsulationBundle data + methods; restrict direct accessprivate/protected/public
AbstractionExpose essential interface, hide implementationAbstract classes, interfaces
InheritanceDerive new class from existing, reuse codeclass D : public B
PolymorphismSame interface, different behaviourVirtual functions, overloading

2. Classes & Objects

class Circle {
private:
    double radius;    // data member (hidden)
public:
    Circle(double r) : radius(r) {}     // constructor
    double area() { return 3.14159 * radius * radius; }  // method
    ~Circle() {}                        // destructor
};

Circle c(5.0);    // object on stack
Circle *p = new Circle(3.0);  // object on heap
delete p;

struct vs class in C++: Only difference — default access. struct: public. class: private.

3. Constructors & Destructors

Types of constructors:
Default: no parameters. Copy: takes const reference to same class. Parameterised: takes other args.

Initialiser list (preferred):

class A {
    int x, y;
public:
    A(int a, int b) : x(a), y(b) {}  // members initialised before constructor body
};

Constructor/Destructor order — critical for GATE:

class A { public: A(){cout<<"A";} ~A(){cout<<"~A";} };
class B : public A { public: B(){cout<<"B";} ~B(){cout<<"~B";} };
B b;  // Output: A B  (on creation)
      //         ~B ~A (on destruction)

Rule: Constructor — Base first, then Derived. Destructor — Derived first, then Base.

4. Inheritance

class Derived : public Base { ... };

Types of inheritance:

Inheritance typeBase publicBase protectedBase private
publicpublicprotectedinaccessible
protectedprotectedprotectedinaccessible
privateprivateprivateinaccessible

Private members of base are never directly accessible in derived (even with public inheritance).
Default inheritance for class: private. For struct: public.

5. Virtual Functions & Polymorphism

Without virtual (static dispatch):

class A { public: void f() { cout << "A"; } };
class B : public A { public: void f() { cout << "B"; } };
A *p = new B;
p->f();   // prints "A" — pointer type is A*, so A::f() called

With virtual (dynamic dispatch):

class A { public: virtual void f() { cout << "A"; } };
class B : public A { public: void f() { cout << "B"; } };
A *p = new B;
p->f();   // prints "B" — object is B, so B::f() called via vtable

vtable: Each class with virtual functions has a vtable (array of function pointers). Each object has a vptr pointing to its class’s vtable. Runtime lookup: vptr → vtable → correct function.

Virtual destructor: Essential when deleting derived object via base pointer.

A *p = new B;
delete p;   // Without virtual ~A(): UB. With virtual ~A(): ~B() then ~A() called.

6. Abstract Classes

Pure virtual function: virtual void f() = 0; — no implementation in class.
Abstract class: any class with ≥1 pure virtual function.
Cannot instantiate: Shape s; — compile error if Shape is abstract.
Must override: Derived class must implement ALL pure virtual functions to be concrete.

class Shape {          // abstract
public:
    virtual double area() = 0;    // pure virtual
    virtual ~Shape() {}           // virtual destructor
};
class Circle : public Shape {     // concrete
    double r;
public:
    Circle(double r) : r(r) {}
    double area() override { return 3.14*r*r; }  // override keyword (C++11)
};

7. Access Specifiers Summary

SpecifierSame classDerived classOutside class
publicYesYesYes
protectedYesYesNo
privateYesNoNo

8. Multiple Inheritance & Diamond Problem

Diamond problem:

     A
    / \
   B   C
    \ /
     D
// D gets TWO copies of A's members — ambiguity

Fix — virtual base class:

class A { public: int x; };
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {};
// Only ONE copy of A in D

Virtual inheritance adds overhead (vptr for virtual base). Constructor of A called by D directly.

9. GATE Examples

GATE 2018 — What is the output?

class A {
public:
    A() { cout << "A "; }
    ~A() { cout << "~A "; }
};
class B : public A {
public:
    B() { cout << "B "; }
    ~B() { cout << "~B "; }
};
int main() { B b; }

Constructor: A first (base), then B (derived). Destructor (on scope exit): ~B first, then ~A.
Output: A B ~B ~A

GATE 2020 — What is the output?

class A {
public:
    virtual void f() { cout << "A"; }
};
class B : public A {
public:
    void f() { cout << "B"; }
};
A *p = new B;
p->f();

Virtual dispatch: object is B, so B::f() is called. Output: B

GATE 2022 — Can you instantiate this class?

class X {
public:
    virtual void g() = 0;
    void h() { cout << "h"; }
};
X obj;    // ?

X has a pure virtual function g() — X is abstract. X obj; is a compile error.

10. Common Mistakes

  • Non-virtual destructor in polymorphic base: A *p = new B; delete p; with non-virtual destructor calls only A’s destructor — B’s destructor skipped, causing memory/resource leaks.
  • Forgetting override keyword: Without override, a function in the derived class with wrong signature silently creates a new function instead of overriding — the virtual dispatch doesn’t reach it.
  • Accessing private base members in derived: Private members are never accessible in derived class even with public inheritance. Use protected for members that derived classes need to access.
  • Constructor order confusion: Base constructor is always called before derived, regardless of order in derived’s initializer list. Destructor order is always reversed.
  • Calling virtual functions from constructor/destructor: Virtual dispatch does NOT work in constructors/destructors — the call goes to the class being currently constructed, not the most-derived class.

11. FAQ

What is the difference between virtual and non-virtual functions in C++?
Non-virtual functions use static dispatch — the function called is determined at compile time based on the pointer/reference type. Virtual functions use dynamic dispatch via vtable — the function called is determined at runtime based on the actual object type. This is what makes runtime polymorphism possible: a Base* pointing to a Derived object will call Derived’s virtual function, not Base’s.
What is the order of constructor and destructor calls in inheritance?
Constructors execute base-first: if D inherits from C inherits from B inherits from A, the order is A→B→C→D. Destructors execute in reverse: D→C→B→A. This guarantees the base class is fully constructed before derived adds to it, and derived is fully destroyed before base tears down.
What is a pure virtual function and abstract class?
A pure virtual function is declared with = 0 in the base class and has no implementation there. Any class containing at least one pure virtual function is abstract — it cannot be instantiated. Derived classes must provide implementations for all pure virtual functions (otherwise they too are abstract). Abstract classes act as interfaces in C++.
What is the diamond problem in multiple inheritance?
When class D inherits from B and C, and both B and C inherit from A, D gets two separate copies of A’s members (one through B, one through C). Accessing A’s members from D is ambiguous. The fix is virtual inheritance: class B : virtual public A and class C : virtual public A — this ensures only one shared copy of A exists in D.