CSE202Semester 3 • 4 CreditsCore Subjects

Object Oriented Programming

This course develops C++ programming and object-oriented programming skills through topics including classes, functions, pointers, constructors, file handling, operator overloading, inheritance, polymorphism, exception handling, templates, and the Standard Template Library. Students apply these concepts to solve programming problems and build software applications.

Syllabus PDF
6 Units • Notes • Model Answers • MCQs
Select Course Unit (6 Units)
Active: Unit 1
Unit 1:C++ Programming Basics and Functions
25 mins•High-Yield Unit Guide

C++ Programming Basics and Functions

Unit 1 Exam Focus & Core Takeaways

Review the core definitions, standard architectures, and syntax patterns below. Pay special attention to sections highlighted with bullet points for your mid-term and end-term subjective questions.

Unit 1: C++ Programming Basics and Functions

1. Executive Summary & Overview

C++ is a multi-paradigm, statically typed, compiled programming language originally conceived by Bjarne Stroustrup as "C with Classes" at Bell Laboratories. By marrying the raw hardware execution speed and memory manipulation capabilities of C with high-level object-oriented and generic abstractions, C++ serves as the bedrock for modern systems engineering, game engines, embedded systems, and high-performance financial infrastructure. This unit establishes the core computational foundations of C++: the transition from Procedural Oriented Programming (POP) to Object-Oriented Programming (OOP), the anatomy of classes and objects, access specifiers, static members, friendship relationships, stream-based input/output via <iostream> and <iomanip>, reference semantics, and advanced function mechanics including function overloading, default arguments, inline expansion, and recursion.


2. The Object-Oriented Paradigm vs. Procedural Programming

Before the emergence of OOP, software systems predominantly followed Procedural Oriented Programming (POP), as exemplified by C, Pascal, and Fortran.

CODE
+--------------------------------------------------------------------------+
| PROCEDURAL ORIENTED (POP)            OBJECT-ORIENTED (OOP)               |
+--------------------------------------------------------------------------+
| Focus: Algorithms & Actions          Focus: Data Entities & State        |
| Structure: Monolithic functions      Structure: Classes & Encapsulated   |
|            operating on global data             Objects                  |
| Data Security: Vulnerable; functions Data Security: High; data hidden    |
|                share global state               via private access       |
| Approach: Top-Down design            Approach: Bottom-Up composition     |
| Maintenance: High coupling causes    Maintenance: Low coupling; modular  |
|              cascading bug ripple                 polymorphic extension  |
+--------------------------------------------------------------------------+

The Four Pillars of Object-Oriented Programming:

  1. Encapsulation: The bundling of data attributes and the member functions that manipulate them into a single cohesive unit (class), shielding internal representations from unauthorized external tampering.
  2. Data Abstraction: Exposing only the essential interface mechanisms to the outside world while concealing low-level implementation complexities.
  3. Inheritance: The mechanism by which a derived child class inherits fields and behaviors from an existing base class, enabling hierarchical classification and code reuse.
  4. Polymorphism: The ability of a message, operator, or function call to exhibit different behaviors depending on the context or dynamic type of the target object (static/compile-time vs. dynamic/runtime polymorphism).

3. C++ Compilation Pipeline & Namespaces

A C++ source file (.cpp) undergoes four discrete transformation stages before becoming an executable binary:

CODE
[ Source: .cpp ] ---> [ 1. Preprocessor: g++ -E ] ---> Expanded Code (macros expanded, headers included)
                                 |
                                 v
                      [ 2. Compiler: g++ -S ]     ---> Assembly Code (.s)
                                 |
                                 v
                      [ 3. Assembler: g++ -c ]    ---> Relocatable Object File (.o / .obj)
                                 |
                                 v
                      [ 4. Linker: ld ]           ---> Executable Binary (.exe / a.out)
                      (Links external libs & symbols)

Namespaces and the std Scope

Namespaces prevent identifier collisions across large-scale software libraries.

cpp
namespace MathEngine {
    double calculateArea(double radius) { return 3.14159 * radius * radius; }
}

namespace GraphicEngine {
    void calculateArea() { /* Renders screen area */ }
}

// Scope resolution operator (::) specifies exact symbol context:
double r = MathEngine::calculateArea(5.0);

Best Practice: Avoid placing using namespace std; in header files (.h / .hpp), as it pollutes the global namespace for all translation units that include that header.


4. Classes, Objects, and Encapsulated Data Types

A class is a user-defined blueprint or user-defined type, whereas an object is an instantiated, concrete variable of that class occupying real memory in the runtime stack or heap.

cpp
class BankAccount {
private:
    std::string accountNumber; // Private data member (hidden)
    double balance;

public:
    // Member function declared inside, defined inside (implicit inline)
    void deposit(double amount) {
        if (amount > 0) balance += amount;
    }

    // Member function declared inside, defined outside via scope resolution
    bool withdraw(double amount);

    // Const-qualified getter: promises not to mutate object state
    double getBalance() const { return balance; }
};

// Definition outside class using scope resolution operator (::)
bool BankAccount::withdraw(double amount) {
    if (amount > 0 && balance >= amount) {
        balance -= amount;
        return true;
    }
    return false;
}

Member Access Specifiers:

  • private: Accessible only by member functions and declared friend functions/classes of the containing class. (Default specifier for class).
  • public: Accessible by any function anywhere in the program where the object is in scope.
  • protected: Accessible within the containing class and any derived (subclassed) classes, but private to external clients.

Comparing class, struct, union, and enum class:

ConstructDefault Member AccessDefault Inheritance AccessMemory Allocation StrategyPrimary Purpose
classprivateprivateContiguous sum of all member fields (plus alignment padding)Encapsulated OOP with state invariants
structpublicpublicContiguous sum of all member fieldsPlain Data Aggregates (POD / DTOs)
unionpublicN/A (cannot inherit)Overlapped storage; size equals largest memberMemory conservation; mutually exclusive variants
enum classN/AN/AUnderlying integral type (e.g., int, uint8_t)Strongly typed, scoped enumeration constants

5. Advanced Class Mechanisms: Static Members and Friendship

A. Static Data Members and Member Functions

A static data member is a class-level variable shared by all instances of that class. It does not occupy space inside individual object instances; it resides in the static/global data segment.

cpp
class ServerConnection {
private:
    int socketId;
    static int activeConnections; // Declaration only

public:
    ServerConnection(int id) : socketId(id) { activeConnections++; }
    ~ServerConnection() { activeConnections--; }

    // Static member function: lacks a 'this' pointer; can only touch static members
    static int getActiveCount() {
        return activeConnections;
    }
};

// Mandatory external definition in file scope (prior to C++17 inline static)
int ServerConnection::activeConnections = 0;

// Invocation without creating an object instance:
int count = ServerConnection::getActiveCount();

B. Friend Functions and Friend Classes

The friend keyword allows external non-member functions or other classes to access the private and protected internals of a class.

cpp
class Matrix; // Forward declaration

class Vector {
private:
    float coordinates[4];
public:
    // Declare external function as a friend
    friend Vector multiply(const Matrix& m, const Vector& v);
    // Declare an entire external class as a friend
    friend class GraphicsPipeline;
};

Key Properties of Friendship:

  1. Not Symmetric: If class A declares class B as a friend, B can access A's privates, but A cannot access B's privates unless explicitly granted.
  2. Not Transitive: If A friends B, and B friends C, C does not automatically receive access to A.
  3. Not Inherited: Friendship is not passed down to derived child classes.

6. Stream-Based Input/Output and Manipulators

C++ replaces C's weakly typed printf and scanf with strongly typed, type-safe streams defined in <iostream>.

CODE
                  [ ios_base ]
                       |
                   [ ios ]
                   /                 [ istream ]  [ ostream ]
                \            /
                 \          /
                 [ iostream ]

Core Stream Objects:

  • std::cin: Standard input stream (buffered, tied to standard input).
  • std::cout: Standard output stream (buffered, normal program output).
  • std::cerr: Standard error stream (unbuffered, guarantees immediate flushing for critical crash/error diagnostics).
  • std::clog: Standard logging stream (buffered, for general execution tracking).

Stream State Flags & Error Recovery:

Streams maintain internal bitmask state flags:

  • good(): Next operation may succeed; no error flags set.
  • eof(): Reached End-of-File marker.
  • fail(): Logical conversion error (e.g., trying to read alphabetic characters into an int).
  • bad(): Irrecoverable hardware/stream integrity error.
cpp
int age;
std::cout << "Enter age: ";
if (!(std::cin >> age)) {
    // Stream entered fail state
    std::cin.clear(); // Reset state flags back to goodbit
    std::cin.ignore(10000, '
'); // Purge faulty characters up to newline
    std::cerr << "Invalid integer input. Stream cleared.
";
}

Stream Manipulators (<iomanip>):

Manipulators alter stream formatting states:

  • Unparameterized: std::endl (writes AND forces a stream flush), std::boolalpha (prints true/false), std::hex, std::dec.
  • Parameterized (<iomanip>): std::setw(int n) (applies only to the immediate next field), std::setprecision(int n), std::setfill(char c), std::fixed.
cpp
#include <iomanip>
std::cout << std::fixed << std::setprecision(2);
std::cout << "$" << std::setw(8) << std::setfill('0') << 42.5; 
// Output: $00042.50

7. Function Mechanics: Overloading, Defaults, References, and Inlining

A. Reference Variables

A reference (Type&) is an immutable alias or alternative name for an existing, initialized variable. Once bound at initialization, it cannot be reseated to point to another object.

  • Pointers vs. References:
    • References cannot be null (must bind to valid storage).
    • References do not require dereferencing operators (* or ->).
    • References cannot be uninitialized.
cpp
int x = 100;
int& refX = x; // refX is an alias for x
refX = 250;    // x becomes 250

const int& constRef = 500; // Const reference can bind to an rvalue temporary!

B. Parameter Passing Semantics: Value vs. Address vs. Reference

cpp
// 1. Call by Value: Copies argument into new local variable; expensive for large structs
void mutateValue(int a) { a += 10; }

// 2. Call by Address (Pointer): Passes memory address; allows nullptr; requires explicit dereferencing
void mutatePointer(int* p) { 
    if (p) *p += 10; 
}

// 3. Call by Reference: Passes alias to caller's object; zero copy overhead; clean syntax
void mutateReference(int& r) { r += 10; }

// 4. Pass by Const Reference: Idiomatic C++ for non-primitive inputs (zero copy + read-only safety)
void printData(const std::string& str) { std::cout << str << '
'; }

C. Function Overloading & Resolution Rules

C++ permits multiple functions to share the identical identifier within the same scope, provided their parameter lists differ in type, count, or order.

  • Return Type Invariance: Changing only the return type cannot overload a function (e.g., int compute() and double compute() trigger a compiler collision).
  • Overload Resolution Steps:
    1. Exact match (trivial conversions like array-to-pointer or adding const).
    2. Promotion (e.g., char / short to int, float to double).
    3. Standard conversion (e.g., int to double, derived-pointer to base-pointer).
    4. User-defined conversions (constructors / conversion operators).
    5. Ellipsis (...) match.

D. Default Arguments

Default parameter values are substituted by the compiler at the call site if omitted by the caller:

  • Trailing Rule: Default parameters must be specified from right-to-left; once a parameter receives a default, all subsequent parameters to its right must also have defaults.
  • Declaration Rule: Defaults must typically be specified in the function declaration (header file), not repeated in the definition.
cpp
// Valid:
void configureNetwork(int port, int timeoutMs = 5000, bool enableSSL = true);

// Invalid (violates trailing rule):
// void configureNetwork(int port = 8080, int timeoutMs); 

E. Inline Functions

Declared with the inline keyword, requesting that the compiler substitute the function's machine instructions directly at the call site rather than executing a traditional call jump instruction (avoiding stack frame setup and register saving).

  • Compiler Authority: The compiler treats inline as a hint, not a command. It will ignore inlining for recursive functions, large functions, or functions containing complex loops/switches.
  • Advantage Over C Preprocessor Macros: Unlike #define SQUARE(x) ((x)*(x)), inline functions adhere to proper C++ type safety, scoping rules, and evaluate arguments exactly once, avoiding dangerous side effects (e.g., SQUARE(x++)).

8. Summary & Key Review Takeaways

  • OOP organizes software around encapsulated data objects rather than decoupled procedural algorithms.
  • class members are private by default; struct members are public by default.
  • Static member variables represent class-wide state and must be initialized outside the class body at file scope.
  • friend declarations grant external access, but violate strict encapsulation and are non-symmetric, non-transitive, and non-inherited.
  • Streams (<iostream>) provide type-safe, extensible I/O; std::cerr is unbuffered for immediate error reporting, while std::cout is buffered.
  • References act as permanent aliases; passing by const Type& is the canonical C++ idiom for efficient, immutable object passing.
  • Function overloading requires distinct parameter signatures; return types are ignored during overload resolution.