Object-Oriented Programming and C++

This chapter covers NET's two adjacent sub-items together: the language-independent concepts of object orientation (class, object, instantiation, inheritance, encapsulation, abstract class, polymorphism), and C++ as the language that made these mainstream in systems programming — its own tokens, operators, control flow, parameter passing, virtual functions, constructors/destructors, operator overloading, templates, exception handling and streams. Neither has a GATE CS equivalent.

Class, Object, Inheritance, Encapsulation and Polymorphism

The core OOP vocabulary
TermMeaning
Class / ObjectA class is a blueprint (fields + methods); an object is one instantiated instance of it, with its own copy of the fields.
EncapsulationBundling data with the methods that operate on it, and hiding internal representation behind a public interface (access specifiers public/private/protected).
InheritanceA derived class acquires a base class's members, adding or overriding — models an IS-A relationship (a Dog IS-A Animal).
PolymorphismOne interface, many implementations. COMPILE-TIME (function/operator overloading — resolved by argument types) vs RUN-TIME (virtual functions — resolved by the object's actual type).
Abstract classA class with at least one pure virtual function, so it cannot be instantiated directly — it exists only to be derived from and force derived classes to implement that interface.
🎯 Why polymorphism needs a base-class pointer/reference
Run-time polymorphism only fires through a BASE-CLASS pointer or reference to a derived object — calling a virtual method through the pointer looks up the object's actual (dynamic) type's implementation via a vtable, whereas calling through a plain (non-pointer, non-reference) base-class OBJECT would slice off the derived part and always invoke the base version. This slicing behaviour is the standard trap this sub-item tests.

C++ Tokens, Operators, Parameter Passing and Virtual Functions

  • C++ adds reference parameters (int &x) to C's call-by-value: a reference is an alias for the caller's variable, so void inc(int &x) { x++; } DOES modify the caller's variable directly — no explicit pointer/dereference needed, unlike plain C.
  • Virtual functions: declaring a base-class method virtual makes calls through a base pointer/reference dispatch to the most-derived override at run time; a pure virtual function (= 0) has no base implementation at all and makes the class abstract.
  • Constructors and destructors: a constructor runs automatically at object creation (initialising members, often via an initialiser list for efficiency and for members that must be set once, like references and const fields); a destructor runs automatically at destruction (releasing resources) — a virtual destructor is required on any base class meant to be deleted through a base pointer, or the derived part's destructor is skipped, leaking its resources.

Overloading, Templates, Exception Handling and Streams

  • Operator overloading gives operators (+, <<, ==) new meanings for user-defined types — it never changes an operator's precedence or associativity, only what code runs for a given type combination.
  • Templates give compile-time generic programming: a function or class template is instantiated by the compiler for each concrete type it is actually used with, generating type-specific code with no run-time type-dispatch overhead — distinct from run-time polymorphism, which pays a vtable-lookup cost per call.
  • Exception handling: try/catch/throw separates error-detection code from error-HANDLING code; an exception thrown inside a try block unwinds the stack (running destructors of local objects along the way) until a matching catch handler is found, or the program terminates if none is.
  • Streams and files: cin/cout/cerr are the standard-stream objects overloading >>/<<; ifstream/ofstream extend the same stream abstraction to files, so file I/O uses the identical >>/<< syntax as console I/O.

Multifile Programs

A large C++ program is split into a header file (.h, declarations only — class definitions, function prototypes) included wherever needed, and one or more source files (.cpp, actual definitions), compiled separately into object files and combined by the linker. Header guards (#ifndef/#define/#endif, or #pragma once) prevent the same header's declarations from being processed twice if it is (directly or transitively) included more than once in one translation unit — without them, a class or function would appear 'redefined' to the compiler.

Key takeaways

  • Class is the blueprint, object the instance; encapsulation hides representation behind an interface; inheritance models IS-A; polymorphism is one interface with many implementations, compile-time (overloading) or run-time (virtual functions).
  • Run-time polymorphism fires only through a base-class pointer/reference; calling through a plain base object slices off the derived part.
  • A base class deleted through a base pointer needs a virtual destructor, or the derived part's cleanup is skipped.
  • Templates are compile-time generics (no run-time dispatch cost); virtual functions are run-time polymorphism (a vtable-lookup cost per call) — different mechanisms for different needs.
  • Header guards prevent a header's declarations from being processed twice in one translation unit.

Practice questions (8)

Attempt each one before opening the answer. Every explanation names the tempting wrong option as well as the right one, because that is where marks are lost.

  1. Run-time polymorphism in C++ is triggered when a virtual method is called through:

    1. A base-class pointer or reference bound to a derived object
    2. A plain (non-pointer, non-reference) base-class object
    3. A template instantiation
    4. A preprocessor macro
    Show answer

    Answer: A — A base-class pointer or reference bound to a derived object

    Calling through a base pointer/reference looks up the object's actual dynamic type via the vtable; calling through a plain base object instead slices off the derived part and always invokes the base version.
  2. A class containing at least one pure virtual function is:

    1. Abstract, and cannot be instantiated directly
    2. Guaranteed to have no derived classes
    3. Automatically the base of every other class
    4. Identical in behaviour to a template class
    Show answer

    Answer: A — Abstract, and cannot be instantiated directly

    A pure virtual function (declared with = 0) has no implementation in that class, so an object of it alone would be incomplete — such a class exists only to be derived from, and derived classes must implement the pure virtual function to become instantiable themselves.
  3. Compile-time polymorphism in C++ is achieved through:

    1. Function/operator overloading, resolved by argument types at compile time
    2. Virtual functions
    3. Exception handling
    4. Dynamic memory allocation
    Show answer

    Answer: A — Function/operator overloading, resolved by argument types at compile time

    Overload resolution happens entirely at compile time based on the number and types of arguments; virtual functions, by contrast, are resolved at run time based on the object's actual type — the run-time polymorphism mechanism.
  4. A base class from which objects are deleted through base-class pointers should have:

    1. A virtual destructor
    2. No destructor at all
    3. A template destructor
    4. A private constructor
    Show answer

    Answer: A — A virtual destructor

    Without a virtual destructor, deleting a derived object through a base pointer runs only the base class's destructor, skipping the derived part's cleanup and leaking any resources it held.
  5. A C++ function template, compared to a virtual function, achieves polymorphism at:

    1. Compile time, with no run-time dispatch overhead
    2. Run time only, with a vtable lookup per call
    3. Neither — templates are unrelated to polymorphism
    4. Only when combined with exception handling
    Show answer

    Answer: A — Compile time, with no run-time dispatch overhead

    The compiler instantiates a separate, type-specific version of the template for each type it is used with, so the correct code is selected entirely at compile time with no run-time type-dispatch cost, unlike virtual functions.
  6. When an exception is thrown inside a try block and no matching catch handler exists in the current function:

    1. The stack unwinds further, running local destructors, in search of a matching handler up the call chain
    2. The exception is silently ignored
    3. The program restarts from main
    4. It becomes a compile error
    Show answer

    Answer: A — The stack unwinds further, running local destructors, in search of a matching handler up the call chain

    Stack unwinding continues up the call chain, destroying local objects along the way, until a matching handler is found somewhere up the chain, or the program terminates (typically via std::terminate) if none exists anywhere.
  7. Which of the following are true of C++ reference parameters, as distinct from plain C pointer parameters? (More than one option may be correct.)

    1. A reference is an alias for the caller's variable and needs no explicit dereference operator inside the function
    2. Modifying a reference parameter modifies the caller's original variable
    3. A reference must be null-checked before use, exactly like a pointer
    4. References can be reseated to point at a different variable after initialisation
    Show answer

    Answer: A — A reference is an alias for the caller's variable and needs no explicit dereference operator inside the function; B — Modifying a reference parameter modifies the caller's original variable

    A reference is bound once at initialisation and cannot be reseated, and (unlike a pointer) a well-formed reference cannot be null, so no null-check is idiomatically needed — it is exactly these two properties that make it an alias rather than an address-holding variable.
  8. Name the preprocessor mechanism (three directives, or a single non-standard-but-widely-supported pragma) used to prevent a header file's contents from being processed more than once in one translation unit.

    Numerical answer — type the value.

    Show answer

    Answer: header guard

    An #ifndef/#define/#endif header guard (or the #pragma once shortcut most compilers support) prevents a class or function from appearing 'redefined' when the same header is included, directly or transitively, more than once.