C++ Complete Programming Course โ€“ University Level โ€“ Pak Notes Hub
๐Ÿ’ป University / College Level โ€” BS Computer Science / Software Engineering

C++ Programming
Complete Course

Basics ยท OOP ยท STL ยท Data Structures ยท Advanced Concepts โ€” Complete Guide in Easy English

๐Ÿ“š 15 Units ๐ŸŽ“ University Level ๐Ÿ’ป Code Examples ๐Ÿ“ Practice Programs ๐Ÿ”ฅ Real Projects
Unit 1

Introduction to C++ Programming

Understanding C++ language, its history, features, and basic program structure

What is C++?

C++ is a powerful, high-performance programming language that supports both procedural and object-oriented programming (OOP). It was developed by Bjarne Stroustrup at Bell Labs in 1979 as an extension of the C programming language.

๐Ÿ’ก C++ = C with Classes: Initially called "C with Classes", it was renamed C++ in 1983. The "++" operator in C means increment by 1, signifying C++ is one step ahead of C!

History of C++

  • 1979: Bjarne Stroustrup starts work on "C with Classes"
  • 1983: Renamed to C++
  • 1985: First commercial release
  • 1998: C++98 (First ISO Standard)
  • 2011: C++11 (Major update with modern features)
  • 2014: C++14 (Bug fixes & improvements)
  • 2017: C++17 (New features)
  • 2020: C++20 (Latest standard with modules, concepts)

Features of C++

๐Ÿš€ Fast Performance
๐ŸŽฏ Object-Oriented
๐Ÿ’ป Platform Independent
๐Ÿ”ง Low-Level Manipulation
๐Ÿ“š Rich Library Support
๐Ÿ” Reusability (OOP)
โš™๏ธ Compiled Language
๐ŸŽจ Supports Multiple Paradigms

Detailed Features:

  • Object-Oriented: Supports classes, objects, inheritance, polymorphism, encapsulation
  • Fast & Efficient: Compiles to machine code, no runtime overhead
  • Portable: Write once, compile anywhere (with recompilation)
  • Rich Standard Library: STL (containers, algorithms, iterators)
  • Pointers: Direct memory access & manipulation
  • Multi-paradigm: Procedural, OOP, Generic, Functional programming
  • Case-Sensitive: Variable and variable are different

Advantages of C++

AdvantageExplanation
High PerformanceCompiles to native code, no interpreter overhead, close to hardware
Memory ControlManual memory management with new/delete, pointers for precise control
OOP SupportCode reusability, modularity, easier maintenance through classes & objects
Large CommunityExtensive resources, libraries, frameworks, help available
Industry StandardUsed in game dev, system software, embedded systems, competitive programming
Backward CompatibleMost C code works in C++, easy migration
STLReady-made data structures & algorithms (vectors, maps, sort, search)

Disadvantages of C++

DisadvantageExplanation
Complex SyntaxSteeper learning curve than Python, Java due to pointers, templates, multiple paradigms
Manual Memory ManagementProgrammer must handle memory allocation/deallocation, risk of memory leaks
No Garbage CollectionUnlike Java/C#, no automatic memory cleanup (modern C++ has smart pointers)
Security IssuesBuffer overflows, pointer errors can cause crashes or security vulnerabilities
Longer CompilationLarge projects take time to compile compared to interpreted languages
Platform-Specific CodeSome features are OS-dependent, need recompilation for different platforms

C vs C++

FeatureCC++
ParadigmProceduralProcedural + OOP + Generic
FocusFunctionsClasses & Objects
OOP SupportโŒ Noโœ… Yes (classes, inheritance, polymorphism)
Data SecurityLess (no encapsulation)More (private/public access control)
OverloadingโŒ No function overloadingโœ… Function & operator overloading
ReferencesโŒ Noโœ… Yes
Exception HandlingโŒ No (use error codes)โœ… try-catch blocks
TemplatesโŒ Noโœ… Generic programming
STLโŒ Noโœ… Rich library (vector, map, etc.)
File Extension.c.cpp, .cc, .cxx

Applications of C++

  • Operating Systems: Windows, Linux, macOS (parts written in C++)
  • Game Development: Unreal Engine, Unity (backend), AAA games
  • Web Browsers: Chrome (V8 engine), Firefox, Safari
  • Database Systems: MySQL, PostgreSQL, MongoDB
  • Embedded Systems: IoT devices, automotive software, medical devices
  • Graphics & Animation: Adobe products, Autodesk Maya, 3D rendering
  • Compilers: GCC, Clang (written in C++)
  • Scientific Computing: Simulation software, numerical analysis
  • Financial Systems: Trading platforms, banking software (speed critical)
  • Competitive Programming: Codeforces, LeetCode, ACM ICPC

Basic C++ Program Structure

// My First C++ Program
#include <iostream>     // Preprocessor directive (include header file)
using namespace std;     // Use standard namespace

int main() {                  // Main function - program entry point
    cout << "Hello, World!"; // Output to console
    return 0;                  // Return 0 indicates successful execution
}

Line-by-Line Explanation:

  • #include <iostream>: Includes input/output stream library for cin, cout
  • using namespace std;: Tells compiler to use standard namespace (so we can write cout instead of std::cout)
  • int main(): Main function where program execution begins. Returns integer (0 = success)
  • cout << "Hello, World!";: Prints text to console. << is insertion operator
  • return 0;: Returns 0 to operating system (indicates program ran successfully)
  • Semicolon (;): Statement terminator in C++
  • Curly Braces { }: Define code blocks (function body)

Compilation Process

C++ is a compiled language. Your code goes through multiple stages:

Compilation Process Flow

Source Code (.cpp)
        โ†“
Preprocessing (#include, #define expanded)
        โ†“
Compilation (converts to assembly code)
        โ†“
Assembly (converts to machine code .obj/.o)
        โ†“
Linking (links with libraries, creates .exe)
        โ†“
Executable File (.exe on Windows, no extension on Linux)

Common Compilers:

  • GCC (g++): GNU Compiler Collection (Linux, macOS, Windows via MinGW)
  • Clang: LLVM-based compiler (faster compilation, better error messages)
  • MSVC: Microsoft Visual C++ (Windows, Visual Studio)
  • Intel C++: Optimized for Intel processors

Compiling from Command Line:

// Compile with g++
g++ program.cpp -o program.exe

// Run the program
./program.exe     (Windows)
./program         (Linux/Mac)

Input & Output in C++

Output using cout:

#include <iostream>
using namespace std;

int main() {
    cout << "Hello World";          // Print text
    cout << "Welcome to C++";      // On same line
    cout << endl;                      // New line
    
    // Multiple outputs
    cout << "Name: " << "Ali" << endl;
    cout << "Age: " << 20 << endl;
    
    // Using \n for new line
    cout << "Line 1\n";
    cout << "Line 2\n";
    
    return 0;
}

Input using cin:

#include <iostream>
using namespace std;

int main() {
    int age;
    string name;
    
    cout << "Enter your name: ";
    cin >> name;                      // Input operator
    
    cout << "Enter your age: ";
    cin >> age;
    
    cout << "Name: " << name << endl;
    cout << "Age: " << age << endl;
    
    return 0;
}

Comments in C++

// Single-line comment (use // for one line)

/*
   Multi-line comment
   Use /* ... */ for multiple lines
   Everything between /* and */ is ignored by compiler
*/

int x = 10;  // You can add comments after code too

// Comments are important for:
// 1. Code documentation
// 2. Explaining complex logic
// 3. Temporarily disabling code during testing

C++ IDEs & Text Editors

ToolTypePlatformBest For
Visual StudioIDEWindowsProfessional development, debugging
VS CodeEditorAllLightweight, extensions, modern UI
Code::BlocksIDEAllBeginners, free, simple
CLionIDEAllProfessional, paid, intelligent code completion
Dev-C++IDEWindowsBeginners (outdated but simple)
Eclipse CDTIDEAllLarge projects, Java devs familiar
Sublime TextEditorAllFast, lightweight, customizable
Vim/NeovimEditorAllAdvanced users, terminal-based

Writing Your First Program

Example: Simple Calculator

#include <iostream>
using namespace std;

int main() {
    int num1, num2, sum;
    
    cout << "Enter first number: ";
    cin >> num1;
    
    cout << "Enter second number: ";
    cin >> num2;
    
    sum = num1 + num2;
    
    cout << "Sum = " << sum << endl;
    
    return 0;
}

Output:

Enter first number: 15
Enter second number: 25
Sum = 40
โœ๏ธ Practice: Write a C++ program that takes your name, age, and city as input, then displays them in a formatted way. Example output: "My name is Ali, I am 20 years old, and I live in Lahore."
Unit 2

Data Types & Variables

Understanding different types of data and how to store them in memory

What is a Variable?

A variable is a named storage location in memory that holds a value. Think of it as a labeled box where you can store data and retrieve it later.

int age = 25;        // Variable 'age' stores integer 25
string name = "Ali"; // Variable 'name' stores string "Ali"

Variable Naming Rules:

  • Must start with letter (a-z, A-Z) or underscore (_)
  • Can contain letters, digits (0-9), underscores
  • Cannot use C++ keywords (int, if, while, etc.)
  • Case-sensitive (Age and age are different)
  • No spaces allowed
  • Good Practice: Use meaningful names (age, studentName) not (a, x, temp)

Valid vs Invalid Variable Names:

Valid โœ…Invalid โŒReason
age2ageCannot start with digit
student_namestudent-nameHyphen not allowed
_temptemp valueSpace not allowed
total123int'int' is a keyword
myVarmy$Var$ not allowed

Data Types in C++

Data types specify what kind of value a variable can hold and how much memory it occupies.

1. Fundamental (Built-in) Data Types:

TypeSize (bytes)RangeExample
int4-2,147,483,648 to 2,147,483,647int age = 25;
short2-32,768 to 32,767short marks = 95;
long4 or 8Very large integerslong population = 220000000;
long long8-9 quintillion to 9 quintillionlong long big = 9000000000;
float4ยฑ3.4 ร— 1038 (6-7 digits precision)float pi = 3.14f;
double8ยฑ1.7 ร— 10308 (15-16 digits)double price = 1599.99;
char1-128 to 127 (or 0 to 255 unsigned)char grade = 'A';
bool1true (1) or false (0)bool isStudent = true;

Type Modifiers

Modifiers change the range and behavior of data types:

  • signed: Can store positive and negative (default for int, char)
  • unsigned: Only positive values (doubles the positive range)
  • short: Reduces size (short int)
  • long: Increases size (long int, long double)
unsigned int rollNo = 12345;      // Only positive, 0 to 4,294,967,295
signed int temperature = -10;     // Can be negative
long long bigNumber = 9876543210; // Very large number
unsigned char letter = 255;       // 0 to 255 range

Integer Types Examples

#include <iostream>
using namespace std;

int main() {
    int age = 20;
    short marks = 95;
    long population = 220000000;
    unsigned int rollNo = 12345;
    
    cout << "Age: " << age << endl;
    cout << "Marks: " << marks << endl;
    cout << "Population: " << population << endl;
    cout << "Roll No: " << rollNo << endl;
    
    return 0;
}

Floating-Point Types

TypePrecisionWhen to Use
float6-7 digitsGraphics, games (less precision needed, saves memory)
double15-16 digitsScientific calculations, financial data (default choice)
long double18-19 digitsVery high precision calculations
float pi = 3.14159f;            // Note the 'f' suffix for float
double price = 1599.99;         // More precise
long double precise = 3.141592653589793238;

cout << "Pi (float): " << pi << endl;           // 3.14159
cout << "Price (double): " << price << endl;   // 1599.99
๐Ÿ’ก float vs double: Always use 'f' suffix for float literals (3.14f). Without it, compiler treats decimal numbers as double by default, then converts to float (wastes performance).

Character Type (char)

Stores single character in single quotes.

char grade = 'A';
char symbol = '$';
char digit = '5';        // Character '5', not integer 5

cout << grade << endl;   // Output: A

// Characters are stored as ASCII values (integers)
cout << (int)grade << endl;  // Output: 65 (ASCII of 'A')

Common ASCII Values:

  • 'A' to 'Z': 65 to 90
  • 'a' to 'z': 97 to 122
  • '0' to '9': 48 to 57
  • Space: 32
  • Newline '\n': 10

Boolean Type (bool)

Stores logical values: true or false.

bool isStudent = true;
bool hasPassed = false;
bool isAdult = (age >= 18);  // Result of comparison

cout << isStudent << endl;      // Output: 1 (true = 1, false = 0)
cout << hasPassed << endl;      // Output: 0

// Use boolalpha to print true/false instead of 1/0
cout << boolalpha << isStudent << endl;  // Output: true

String Type

Stores sequence of characters (text). Not a fundamental type, it's a class from C++ Standard Library.

#include <iostream>
#include <string>      // Must include string header
using namespace std;

int main() {
    string name = "Ali Ahmed";
    string city = "Lahore";
    
    cout << "Name: " << name << endl;
    cout << "City: " << city << endl;
    
    // String concatenation
    string fullInfo = name + " from " + city;
    cout << fullInfo << endl;  // Ali Ahmed from Lahore
    
    return 0;
}

Type Conversion (Casting)

1. Implicit Conversion (Automatic):

int x = 10;
double y = x;      // int automatically converted to double (10.0)

float a = 3.14f;
int b = a;         // float to int (data loss: b = 3)

2. Explicit Conversion (Manual Casting):

// C-style cast
double pi = 3.14159;
int intPi = (int)pi;           // intPi = 3

// C++ style cast (preferred)
int intPi2 = static_cast<int>(pi);  // More readable, safer

// Character to integer
char ch = 'A';
int ascii = (int)ch;            // ascii = 65

Type Conversion Rules:

  • Widening (Safe): char โ†’ int โ†’ long โ†’ float โ†’ double (no data loss)
  • Narrowing (Risky): double โ†’ float โ†’ long โ†’ int โ†’ char (data loss possible)
  • Integer Division: 7/2 = 3 (not 3.5), use 7.0/2 or cast one operand to double

Constants

Values that cannot be changed after initialization.

// Using const keyword
const int MAX_AGE = 100;
const double PI = 3.14159;

// Using #define (preprocessor directive - old style)
#define MAX_SIZE 1000
#define TAX_RATE 0.16

// Trying to change const gives error
// MAX_AGE = 50;  // ERROR: Cannot modify const

const vs #define:

Featureconst#define
Type Safetyโœ… Type-checked by compilerโŒ No type checking (text replacement)
Scopeโœ… Follows scope rulesโŒ Global (file-wide)
Debuggingโœ… Easier to debugโŒ Harder (preprocessor replaces text)
MemoryOccupies memoryNo memory (text substitution)
Recommendationโœ… Use this (modern C++)โŒ Avoid (legacy)

sizeof() Operator

Returns size of data type or variable in bytes.

#include <iostream>
using namespace std;

int main() {
    cout << "Size of int: " << sizeof(int) << " bytes" << endl;
    cout << "Size of double: " << sizeof(double) << " bytes" << endl;
    cout << "Size of char: " << sizeof(char) << " bytes" << endl;
    cout << "Size of bool: " << sizeof(bool) << " bytes" << endl;
    
    int arr[10];
    cout << "Size of array: " << sizeof(arr) << " bytes" << endl; // 40 bytes (10ร—4)
    
    return 0;
}
โœ๏ธ Practice: Write a program that declares variables of all data types (int, float, double, char, bool, string) with meaningful names and values, then prints them. Example: int studentAge = 20, double testScore = 95.5, etc.
Unit 3

Control Structures

Decision making and flow control using if-else, switch, and loops

What are Control Structures?

Control structures determine the order in which statements are executed. They allow programs to make decisions, repeat actions, and choose different paths based on conditions.

Types:

  • Sequential: Statements execute one after another (default)
  • Selection/Decision: if, if-else, nested if, switch
  • Iteration/Loops: for, while, do-while
  • Jump: break, continue, goto, return

1. if Statement

Executes code block only if condition is true.

int age = 20;

if (age >= 18) {
    cout << "You are an adult" << endl;
}
// If condition false, this block is skipped

2. if-else Statement

int marks = 55;

if (marks >= 50) {
    cout << "Pass" << endl;
} else {
    cout << "Fail" << endl;
}

3. if-else if-else Ladder

int marks = 75;

if (marks >= 80) {
    cout << "Grade: A" << endl;
} else if (marks >= 70) {
    cout << "Grade: B" << endl;
} else if (marks >= 60) {
    cout << "Grade: C" << endl;
} else if (marks >= 50) {
    cout << "Grade: D" << endl;
} else {
    cout << "Grade: F (Fail)" << endl;
}

4. Nested if

int age = 25;
bool hasLicense = true;

if (age >= 18) {
    if (hasLicense) {
        cout << "You can drive" << endl;
    } else {
        cout << "Get a license first" << endl;
    }
} else {
    cout << "You are too young to drive" << endl;
}

Relational Operators

OperatorMeaningExampleResult
==Equal to5 == 5true
!=Not equal to5 != 3true
>Greater than5 > 3true
<Less than5 < 3false
>=Greater than or equal5 >= 5true
<=Less than or equal5 <= 3false

Logical Operators

OperatorMeaningExampleResult
&&AND (both must be true)true && falsefalse
||OR (at least one true)true || falsetrue
!NOT (inverts boolean)!truefalse
int age = 25;
bool isStudent = true;

// AND: Both conditions must be true
if (age >= 18 && isStudent) {
    cout << "Adult student discount available" << endl;
}

// OR: At least one condition must be true
if (age < 18 || age > 60) {
    cout << "Special discount" << endl;
}

// NOT: Inverts the condition
if (!isStudent) {
    cout << "Regular price" << endl;
}

5. switch Statement

Multi-way branch based on value of expression. Cleaner than long if-else ladder for checking single variable against multiple values.

int day = 3;

switch (day) {
    case 1:
        cout << "Monday" << endl;
        break;
    case 2:
        cout << "Tuesday" << endl;
        break;
    case 3:
        cout << "Wednesday" << endl;
        break;
    case 4:
        cout << "Thursday" << endl;
        break;
    case 5:
        cout << "Friday" << endl;
        break;
    case 6:
        cout << "Saturday" << endl;
        break;
    case 7:
        cout << "Sunday" << endl;
        break;
    default:
        cout << "Invalid day" << endl;
}
๐Ÿ’ก break is important! Without break, execution "falls through" to next case. This is usually unintended behavior. Default case executes if no case matches.

switch vs if-else:

Featureswitchif-else
Use CaseSingle variable, multiple exact valuesComplex conditions, ranges
PerformanceFaster (jump table)Slower (checks each condition)
ReadabilityCleaner for many valuesBetter for complex logic
Data Typesint, char, enum onlyAny type, any comparison
RangesโŒ Cannot check rangesโœ… Can check ranges (age > 18)

Loops (Iteration)

Repeat a block of code multiple times.

1. for Loop

Used when number of iterations is known.

// Print numbers 1 to 10
for (int i = 1; i <= 10; i++) {
    cout << i << " ";
}
cout << endl;
// Output: 1 2 3 4 5 6 7 8 9 10

// Syntax: for (initialization; condition; increment/decrement)

for Loop Explained:

  • Initialization: int i = 1 (executed once at start)
  • Condition: i <= 10 (checked before each iteration)
  • Increment: i++ (executed after each iteration)
// Print even numbers from 2 to 20
for (int i = 2; i <= 20; i += 2) {
    cout << i << " ";
}

// Print numbers in reverse
for (int i = 10; i >= 1; i--) {
    cout << i << " ";
}

2. while Loop

Repeats while condition is true. Condition checked before each iteration.

int i = 1;

while (i <= 5) {
    cout << i << " ";
    i++;
}
// Output: 1 2 3 4 5

3. do-while Loop

Executes at least once, then repeats while condition is true. Condition checked after each iteration.

int i = 1;

do {
    cout << i << " ";
    i++;
} while (i <= 5);
// Output: 1 2 3 4 5

// Executes at least once even if condition false
int x = 10;
do {
    cout << "This prints once" << endl;
} while (x < 5);  // Condition false, but body executed once

Loop Comparison:

LoopWhen to UseCondition Check
forKnown iterations (print 1-10, iterate array)Before each iteration
whileUnknown iterations (read until EOF, user says "quit")Before each iteration
do-whileMust execute at least once (menu, input validation)After each iteration

Nested Loops

Loop inside another loop.

// Print multiplication table (1 to 5)
for (int i = 1; i <= 5; i++) {
    for (int j = 1; j <= 10; j++) {
        cout << i << " x " << j << " = " << (i*j) << endl;
    }
    cout << endl;
}

// Print pattern
/*
*
**
***
****
*****
*/
for (int i = 1; i <= 5; i++) {
    for (int j = 1; j <= i; j++) {
        cout << "*";
    }
    cout << endl;
}

break Statement

Exits the loop immediately.

// Find first number divisible by 7 and 3
for (int i = 1; i <= 100; i++) {
    if (i % 7 == 0 && i % 3 == 0) {
        cout << "Found: " << i << endl;
        break;  // Exit loop
    }
}
// Output: Found: 21

continue Statement

Skips current iteration, continues with next.

// Print odd numbers from 1 to 10
for (int i = 1; i <= 10; i++) {
    if (i % 2 == 0) {
        continue;  // Skip even numbers
    }
    cout << i << " ";
}
// Output: 1 3 5 7 9
โœ๏ธ Practice: Write programs: (1) Check if number is even/odd, (2) Find largest of 3 numbers, (3) Print factorial of a number using loop, (4) Print Fibonacci series up to n terms, (5) Check if year is leap year.
Unit 4

Functions in C++

Modular programming using functions for code reusability and organization

What is a Function?

A function is a self-contained block of code that performs a specific task. It can be called multiple times, making code reusable, organized, and easier to maintain.

๐Ÿ’ก Analogy: Think of a function like a recipe. You define it once (write the recipe), then use it whenever needed (cook the dish). You don't need to rewrite the recipe each time!

Advantages of Functions

โ™ป๏ธ Code Reusability
๐Ÿ“ฆ Modularity
๐Ÿ› Easy Debugging
๐Ÿ‘ฅ Team Collaboration
๐Ÿ“ Readable Code
โšก Avoid Redundancy

Function Syntax

// Function Definition
returnType functionName(parameters) {
    // Function body (code to execute)
    return value;  // Optional (not needed for void)
}

// Example:
int add(int a, int b) {
    int sum = a + b;
    return sum;
}

Components:

  • Return Type: Data type of value returned (int, float, void, etc.)
  • Function Name: Identifier (follow variable naming rules)
  • Parameters: Input values (optional). Also called formal parameters
  • Function Body: Code inside { }
  • return Statement: Returns value to caller (not needed for void)

Types of Functions

1. No Arguments, No Return Value

void greet() {
    cout << "Hello, World!" << endl;
}

int main() {
    greet();  // Function call
    return 0;
}

2. No Arguments, With Return Value

int getRandomNumber() {
    return 42;
}

int main() {
    int num = getRandomNumber();
    cout << "Number: " << num << endl;
    return 0;
}

3. With Arguments, No Return Value

void printSum(int a, int b) {
    cout << "Sum: " << (a + b) << endl;
}

int main() {
    printSum(5, 10);  // Output: Sum: 15
    return 0;
}

4. With Arguments, With Return Value

int multiply(int a, int b) {
    return a * b;
}

int main() {
    int result = multiply(4, 5);
    cout << "Result: " << result << endl;  // Output: 20
    return 0;
}

Function Declaration vs Definition

Declaration (Prototype): Tells compiler about function (name, return type, parameters)

Definition: Actual implementation of function

#include <iostream>
using namespace std;

// Function Declaration (Prototype) - placed before main
int add(int, int);  // Parameter names optional in declaration

int main() {
    int result = add(5, 3);
    cout << "Sum: " << result << endl;
    return 0;
}

// Function Definition - can be placed after main
int add(int a, int b) {
    return a + b;
}

Function Call

Three ways to pass arguments to functions:

1. Call by Value (Default)

Copies value to function. Original variable unchanged.

void increment(int x) {
    x = x + 1;
    cout << "Inside function: " << x << endl;  // 11
}

int main() {
    int num = 10;
    increment(num);
    cout << "Outside function: " << num << endl;  // Still 10 (unchanged)
    return 0;
}

2. Call by Reference

Passes address of variable. Changes affect original variable.

void increment(int &x) {  // & means reference
    x = x + 1;
    cout << "Inside function: " << x << endl;  // 11
}

int main() {
    int num = 10;
    increment(num);
    cout << "Outside function: " << num << endl;  // 11 (changed!)
    return 0;
}

3. Call by Pointer

void increment(int *x) {  // * means pointer
    *x = *x + 1;
    cout << "Inside function: " << *x << endl;  // 11
}

int main() {
    int num = 10;
    increment(&num);  // Pass address
    cout << "Outside function: " << num << endl;  // 11 (changed!)
    return 0;
}
MethodSyntaxChanges Original?Use When
Call by Valueint xโŒ NoSmall data, don't need to modify original
Call by Referenceint &xโœ… YesNeed to modify original, avoid copying large data
Call by Pointerint *xโœ… YesDynamic memory, arrays, null checking needed

Default Arguments

Provide default values for parameters. If argument not passed, default used.

int power(int base, int exp = 2) {  // exp defaults to 2
    int result = 1;
    for(int i = 0; i < exp; i++) {
        result *= base;
    }
    return result;
}

int main() {
    cout << power(5) << endl;      // 25 (5^2, uses default)
    cout << power(5, 3) << endl;   // 125 (5^3, overrides default)
    return 0;
}

Rules:

  • Default arguments must be rightmost parameters
  • Once a parameter has default value, all right parameters must also have defaults
  • Defaults specified in declaration, not definition (if separate)

Function Overloading

Multiple functions with same name but different parameters (number, type, or order).

int add(int a, int b) {
    return a + b;
}

double add(double a, double b) {
    return a + b;
}

int add(int a, int b, int c) {
    return a + b + c;
}

int main() {
    cout << add(5, 3) << endl;           // Calls first (int version): 8
    cout << add(5.5, 3.2) << endl;       // Calls second (double version): 8.7
    cout << add(1, 2, 3) << endl;        // Calls third (3 params): 6
    return 0;
}

Overloading Rules:

  • Parameters must differ in number, type, or order
  • Return type alone cannot differentiate overloaded functions
  • Compiler chooses function based on arguments passed

Inline Functions

Request compiler to insert function code at call site (instead of jumping to function). Reduces function call overhead for small functions.

inline int square(int x) {
    return x * x;
}

int main() {
    cout << square(5) << endl;  // Compiler replaces with: cout << 5 * 5;
    return 0;
}

Advantages: Faster execution (no function call overhead)

Disadvantages: Increases code size if function called many times

Use for: Small, frequently called functions (getters, setters)

Recursion

Function calling itself. Useful for problems that can be broken into similar subproblems.

// Factorial using recursion
int factorial(int n) {
    if (n == 0 || n == 1) {
        return 1;  // Base case
    }
    return n * factorial(n - 1);  // Recursive call
}

int main() {
    cout << factorial(5) << endl;  // 120 (5! = 5ร—4ร—3ร—2ร—1)
    return 0;
}

Recursion Requirements:

  • Base Case: Condition to stop recursion (avoid infinite loop)
  • Recursive Case: Function calls itself with modified parameter
  • Progress: Each call moves toward base case

Example: Fibonacci Series

int fibonacci(int n) {
    if (n == 0) return 0;     // Base case 1
    if (n == 1) return 1;     // Base case 2
    return fibonacci(n-1) + fibonacci(n-2);  // Recursive
}

int main() {
    for(int i = 0; i < 10; i++) {
        cout << fibonacci(i) << " ";
    }
    // Output: 0 1 1 2 3 5 8 13 21 34
    return 0;
}

Recursion vs Iteration:

AspectRecursionIteration (Loop)
CodeShorter, elegantLonger sometimes
ReadabilityNatural for tree/graph problemsBetter for simple repetition
MemoryMore (stack frames for each call)Less
SpeedSlower (function call overhead)Faster
Stack OverflowRisk if too many callsNo risk
Use WhenTree traversal, divide & conquer, mathematical functionsSimple repetition, performance critical
โœ๏ธ Practice: Write functions for: (1) Check prime number, (2) Find GCD of two numbers, (3) Convert Celsius to Fahrenheit, (4) Print pattern using recursion, (5) Calculate power using recursion (x^n).
Unit 5

Object-Oriented Programming (OOP) Basics

Understanding classes, objects, encapsulation, and constructors/destructors

What is OOP?

Object-Oriented Programming (OOP) is a programming paradigm based on the concept of "objects" that contain data (attributes) and code (methods). It models real-world entities as objects.

๐Ÿ’ก Real-world Analogy: A car is an object. It has properties (color, model, speed) and behaviors (start, stop, accelerate). Similarly, in OOP, objects have data members and member functions!

OOP vs Procedural Programming

AspectProcedural (C)Object-Oriented (C++)
FocusFunctions/proceduresObjects (data + functions together)
Data SecurityLess (global data accessible)More (encapsulation, private data)
ReusabilityLimitedHigh (inheritance, polymorphism)
Real-world ModelingDifficultEasy (objects represent real entities)
MaintenanceHarder for large projectsEasier (modularity)
ExampleC languageC++, Java, Python

Four Pillars of OOP

1๏ธโƒฃ Encapsulation
Bundling data & methods together, hiding internal details
2๏ธโƒฃ Abstraction
Showing only essential features, hiding implementation
3๏ธโƒฃ Inheritance
Creating new class from existing class (reusability)
4๏ธโƒฃ Polymorphism
Same name, different behaviors (overloading, overriding)

Class & Object

Class: Blueprint/template for creating objects. Defines structure and behavior.

Object: Instance of a class. Actual entity created from class blueprint.

// Class Definition
class Car {
    public:          // Access specifier
        // Data members (attributes/properties)
        string brand;
        string model;
        int year;
        
        // Member functions (methods/behaviors)
        void displayInfo() {
            cout << "Brand: " << brand << endl;
            cout << "Model: " << model << endl;
            cout << "Year: " << year << endl;
        }
};

int main() {
    // Creating objects (instances of class)
    Car car1;  // Object 1
    Car car2;  // Object 2
    
    // Accessing members using dot operator
    car1.brand = "Toyota";
    car1.model = "Corolla";
    car1.year = 2023;
    
    car2.brand = "Honda";
    car2.model = "Civic";
    car2.year = 2022;
    
    car1.displayInfo();
    car2.displayInfo();
    
    return 0;
}

Analogy:

  • Class = Cookie Cutter: Design/template
  • Object = Cookie: Actual item created from template
  • One cookie cutter (class) can make many cookies (objects)

Access Specifiers

Control visibility of class members (data & functions).

SpecifierAccess From ClassAccess From OutsideAccess From Derived Class
publicโœ… Yesโœ… Yesโœ… Yes
privateโœ… YesโŒ NoโŒ No
protectedโœ… YesโŒ Noโœ… Yes
class Student {
    private:     // Accessible only within class
        int rollNo;
        string name;
    
    public:      // Accessible from anywhere
        // Setter methods (to set private data)
        void setData(int r, string n) {
            rollNo = r;
            name = n;
        }
        
        // Getter methods (to get private data)
        void displayData() {
            cout << "Roll No: " << rollNo << endl;
            cout << "Name: " << name << endl;
        }
};

int main() {
    Student s1;
    // s1.rollNo = 101;  // ERROR: rollNo is private
    
    s1.setData(101, "Ali");  // Use public method to set private data
    s1.displayData();
    
    return 0;
}

Why private members?

  • Data Hiding: Protect data from accidental modification
  • Validation: Control how data is set (e.g., age can't be negative)
  • Flexibility: Change internal implementation without affecting outside code

Encapsulation

Wrapping data (variables) and code (methods) together as a single unit. Achieved using classes.

class BankAccount {
    private:
        double balance;  // Hidden from outside
    
    public:
        // Constructor
        BankAccount(double initialBalance) {
            balance = initialBalance;
        }
        
        // Controlled access through methods
        void deposit(double amount) {
            if(amount > 0) {
                balance += amount;
                cout << "Deposited: " << amount << endl;
            }
        }
        
        void withdraw(double amount) {
            if(amount > 0 && amount <= balance) {
                balance -= amount;
                cout << "Withdrawn: " << amount << endl;
            } else {
                cout << "Insufficient balance!" << endl;
            }
        }
        
        void checkBalance() {
            cout << "Balance: " << balance << endl;
        }
};

int main() {
    BankAccount acc(1000);  // Initial balance 1000
    acc.deposit(500);
    acc.withdraw(200);
    acc.checkBalance();  // 1300
    
    // Can't directly access balance: acc.balance = 0; (ERROR)
    return 0;
}

Constructors

Special member function automatically called when object is created. Used to initialize object.

Types of Constructors:

1. Default Constructor (No parameters)

class Box {
    public:
        int length;
        
        // Default Constructor
        Box() {
            length = 0;
            cout << "Default Constructor called" << endl;
        }
};

int main() {
    Box b1;  // Constructor called automatically
    cout << "Length: " << b1.length << endl;  // 0
    return 0;
}

2. Parameterized Constructor

class Rectangle {
    private:
        int length, width;
    
    public:
        // Parameterized Constructor
        Rectangle(int l, int w) {
            length = l;
            width = w;
        }
        
        int area() {
            return length * width;
        }
};

int main() {
    Rectangle r1(10, 5);  // Pass values to constructor
    cout << "Area: " << r1.area() << endl;  // 50
    return 0;
}

3. Copy Constructor

Creates object by copying another object of same class.

class Point {
    public:
        int x, y;
        
        // Parameterized Constructor
        Point(int a, int b) {
            x = a;
            y = b;
        }
        
        // Copy Constructor
        Point(const Point &p) {
            x = p.x;
            y = p.y;
            cout << "Copy Constructor called" << endl;
        }
};

int main() {
    Point p1(10, 20);
    Point p2 = p1;  // Copy constructor called
    
    cout << "p2: (" << p2.x << ", " << p2.y << ")" << endl;  // (10, 20)
    return 0;
}

Constructor Rules:

  • Same name as class
  • No return type (not even void)
  • Automatically called when object created
  • Can be overloaded (multiple constructors with different parameters)
  • If no constructor defined, compiler provides default constructor

Destructor

Special member function automatically called when object is destroyed. Used to release resources (memory, files, etc.).

class Demo {
    public:
        // Constructor
        Demo() {
            cout << "Constructor called" << endl;
        }
        
        // Destructor (~ before class name)
        ~Demo() {
            cout << "Destructor called" << endl;
        }
};

int main() {
    Demo d1;  // Constructor called
    cout << "Inside main" << endl;
    return 0;  // Destructor called when d1 goes out of scope
}
/* Output:
Constructor called
Inside main
Destructor called
*/

Destructor Rules:

  • Same name as class with ~ (tilde) prefix
  • No parameters, no return type
  • Only one destructor per class (cannot be overloaded)
  • Automatically called when object destroyed
โœ๏ธ Practice: Create a Student class with private data members (name, rollNo, marks). Include: (1) Parameterized constructor, (2) Copy constructor, (3) Member functions to set/get data, (4) Calculate percentage, (5) Destructor. Create multiple objects and test all functions.
Unit 6

Inheritance & Access Specifiers

Code reusability through parent-child class relationships

What is Inheritance?

Inheritance is mechanism where new class (derived/child) acquires properties and behaviors of existing class (base/parent). Promotes code reusability.

// Base Class (Parent)
class Animal {
    public:
        void eat() { cout << "Eating..." << endl; }
};

// Derived Class (Child) - inherits from Animal
class Dog : public Animal {
    public:
        void bark() { cout << "Barking..." << endl; }
};

int main() {
    Dog d;
    d.eat();   // Inherited from Animal
    d.bark();  // Own method
}

Types of Inheritance

  • Single: One base, one derived (A โ†’ B)
  • Multiple: One derived, multiple bases (A, B โ†’ C)
  • Multilevel: Chain (A โ†’ B โ†’ C)
  • Hierarchical: One base, multiple derived (A โ†’ B, C, D)
  • Hybrid: Combination of above
โœ๏ธ Practice: Create Person (base) and Student (derived) classes. Student inherits name, age from Person and adds rollNo, marks. Demonstrate inheritance with objects.
Unit 7

Polymorphism & Virtual Functions

Same interface, different implementations - function/operator overloading, virtual functions

Polymorphism Types

1. Compile-time (Static): Function Overloading, Operator Overloading

2. Runtime (Dynamic): Virtual Functions, Function Overriding

// Virtual Function Example
class Shape {
    public:
        virtual void draw() {  // Virtual function
            cout << "Drawing Shape" << endl;
        }
};

class Circle : public Shape {
    public:
        void draw() override {  // Override
            cout << "Drawing Circle" << endl;
        }
};

int main() {
    Shape* s = new Circle();  // Base pointer, derived object
    s->draw();  // Calls Circle's draw (Runtime polymorphism)
    delete s;
}
โœ๏ธ Practice: Create base class Vehicle with virtual function speed(). Derive Car, Bike classes overriding speed(). Demonstrate polymorphism using base pointer.
Unit 8

Pointers & Dynamic Memory

Memory addresses, pointer operations, new/delete operators

Pointer Basics

int x = 10;
int* ptr = &x;  // Pointer stores address of x
cout << *ptr << endl;  // Dereferencing: prints value (10)

// Dynamic Memory
int* p = new int(25);  // Allocate memory on heap
cout << *p << endl;  // 25
delete p;  // Free memory
โœ๏ธ Practice: Create dynamic array using new. Input values, find sum, then delete using delete[].
Unit 9

Arrays & Strings

Collection of elements and string manipulation

Arrays

int arr[5] = {10, 20, 30, 40, 50};
for(int i=0; i<5; i++) cout << arr[i] << " ";

// 2D Array
int matrix[3][3] = {{1,2,3}, {4,5,6}, {7,8,9}};

Strings

string s = "Hello";
cout << s.length() << endl;  // 5
s += " World";  // Concatenation
cout << s.substr(0, 5) << endl;  // "Hello"
โœ๏ธ Practice: Input array, find largest/smallest, reverse array, check palindrome string.
Unit 10

File Handling

Reading from and writing to files

File Operations

#include <fstream>

// Writing to file
ofstream outfile("data.txt");
outfile << "Hello File!" << endl;
outfile.close();

// Reading from file
ifstream infile("data.txt");
string line;
while(getline(infile, line)) {
    cout << line << endl;
}
infile.close();
โœ๏ธ Practice: Create student record system: write student data to file, read and display all records.
Unit 11

Exception Handling

Handling runtime errors gracefully using try-catch

try-catch Block

try {
    int x = 10, y = 0;
    if(y == 0) throw "Division by zero!";
    cout << x/y;
}
catch(const char* msg) {
    cout << "Error: " << msg << endl;
}
โœ๏ธ Practice: Write program with array index exception handling. Catch out-of-bounds access.
Unit 12

Templates & Generic Programming

Write code that works with any data type

Function Templates

template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    cout << add(5, 3) << endl;        // int version
    cout << add(5.5, 3.2) << endl;    // double version
}

Class Templates

template <typename T>
class Pair {
    T first, second;
public:
    Pair(T a, T b) : first(a), second(b) {}
    T getMax() { return (first > second) ? first : second; }
};
โœ๏ธ Practice: Create template function to swap two values. Test with int, double, string.
Unit 13

Standard Template Library (STL)

Pre-built containers, algorithms, and iterators

STL Containers

#include <vector>
#include <map>

// Vector (Dynamic Array)
vector<int> v = {10, 20, 30};
v.push_back(40);  // Add element

// Map (Key-Value pairs)
map<string, int> ages;
ages["Ali"] = 20;
ages["Sara"] = 22;
โœ๏ธ Practice: Use vector to store student marks. Sort using STL sort(). Find average.
Unit 14

Data Structures in C++

Implementing fundamental data structures

Common Data Structures

  • Stack: LIFO (Last In First Out) - push, pop operations
  • Queue: FIFO (First In First Out) - enqueue, dequeue
  • Linked List: Dynamic size, non-contiguous memory
  • Binary Tree: Hierarchical structure, each node has max 2 children
  • Graph: Nodes connected by edges
#include <stack>
stack<int> s;
s.push(10);
s.push(20);
cout << s.top() << endl;  // 20
s.pop();
โœ๏ธ Practice: Implement stack using array. Add push, pop, display operations.
Unit 15

Advanced C++ Topics

Modern C++ features and best practices

C++11/14/17/20 Features

  • auto keyword: Automatic type deduction
  • Range-based for: for(auto x : vector)
  • Lambda expressions: Anonymous functions
  • Smart pointers: unique_ptr, shared_ptr (automatic memory management)
  • Move semantics: Efficient resource transfer
  • constexpr: Compile-time constants
// Modern C++ Examples
auto x = 10;  // auto deduces type as int

vector<int> v = {1, 2, 3, 4, 5};
for(auto num : v) {  // Range-based for
    cout << num << " ";
}

// Lambda function
auto add = [](int a, int b) { return a + b; };
cout << add(5, 3) << endl;  // 8

Best Practices

โœ… Use meaningful variable names
โœ… Follow consistent coding style
โœ… Add comments for complex logic
โœ… Use const for constants
โœ… Prefer references over pointers
โœ… Use smart pointers for dynamic memory
โœ… Handle exceptions properly
โœ… Write modular, reusable code
โœ๏ธ Practice: Revise all concepts. Build a comprehensive project: Student Management System with classes, file I/O, exception handling, and STL containers.

๐ŸŽ‰ Congratulations!

You've completed C++ Programming course! You now have solid foundation in C++ - from basics to advanced OOP, STL, and modern features. Keep practicing and building projects! ๐Ÿ’ป๐Ÿš€

ยฉ 2024 Pak Notes Hub โ€” www.paknoteshub.online

Complete University-Level C++ Programming Notes in Easy English