Back Back

C++ Programming Language

C++ is a powerful, general-purpose programming language developed by Bjarne Stroustrup in 1979 at Bell Labs as an extension of C. It combines low-level control with high-level abstractions, introducing object-oriented programming (OOP) features like classes, inheritance, and polymorphism. C++ is widely used in game development, operating systems, embedded systems, and high-performance applications.

Origin

Created as "C with Classes" in 1979, standardized as C++ in 1998 (C++98), with modern updates (C++11, C++17, C++20).

Features

OOP, generic programming via templates, STL, low-level memory control, high performance, multithreading.

Applications

Game engines (Unreal), browsers (Chrome), OS (Windows), financial systems, VR, and embedded devices.

Why Learn C++?

Did You Know?

C++ powers Adobe Photoshop, Microsoft Windows, and NASA's Mars Rover software.

C++ vs. C: Why C++ is Better

While C is a foundational language, C++ builds upon it with advanced features, making it more versatile and developer-friendly. Here's how C++ improves over C:

Object-Oriented Programming

C++ supports classes, objects, inheritance, and polymorphism, enabling modular and reusable code. C relies on procedural programming, lacking OOP.

Standard Template Library (STL)

C++ offers STL for containers (e.g., vectors, maps) and algorithms (e.g., sort). C requires manual implementation of data structures.

Type Safety and Features

C++ provides templates, namespaces, and exception handling for safer, more organized code. C lacks these, leading to error-prone code.

Modern Features

C++11+ introduces smart pointers, lambdas, and multithreading. C remains low-level with minimal updates.

Limitations of C: No OOP, manual memory management, no STL, limited abstraction, and weaker type checking make C less suitable for complex projects. C++ balances performance with modern programming paradigms.

Benefits of Learning C++

High Performance

C++ offers low-level control, making it ideal for performance-critical applications like games and real-time systems.

Versatility

Used in game development, finance, OS, VR, and embedded systems, C++ is a multi-domain language.

Community and Libraries

Large community and libraries like Boost and Qt simplify development.

Career Opportunities

High demand for C++ developers in game dev, finance, and systems programming with competitive salaries.

Learning Foundation

Mastering C++ teaches OOP, memory management, and system architecture, aiding learning of other languages.

Data Types and Variables

Basic Data Types

C++ requires explicit type declarations for variables, supporting various primitive types.

Type Size (bytes) Description
int 4 Integer numbers
float 4 Single-precision floating-point
double 8 Double-precision floating-point
char 1 Single character
bool 1 True or false
#include 
using namespace std;

int main() {
    int age = 25;
    float height = 5.9;
    char grade = 'A';
    bool isStudent = true;
    cout << "Age: " << age << ", Height: " << height 
         << ", Grade: " << grade << ", Student: " << isStudent << endl;
    return 0;
}

Tip: Use const for variables that shouldn't change, e.g., const int MAX = 100;.

Type Modifiers and Scope

Modifiers adjust type properties; scope determines variable accessibility.

  • signed, unsigned: Control sign of integers
  • short, long: Adjust size
  • auto: Deduce type (C++11)
  • Scope: Local, global, static
#include 
using namespace std;

int globalVar = 10; // Global scope

int main() {
    static int staticVar = 20; // Retains value
    auto x = 3.14; // Deduced as double
    cout << "Global: " << globalVar << ", Static: " << staticVar 
         << ", Auto: " << x << endl;
    return 0;
}

Tip: Avoid global variables to prevent unintended side effects.

Operators in C++

Arithmetic Operators

Perform mathematical computations.

  • +, -: Add, subtract
  • *, /: Multiply, divide
  • %: Modulus
#include 
using namespace std;

int main() {
    int a = 10, b = 3;
    cout << "Sum: " << a + b << ", Mod: " << a % b << endl;
    return 0;
}

Relational and Logical

Compare values or combine conditions.

  • ==, !=: Equality
  • &&, ||, !: AND, OR, NOT
#include 
using namespace std;

int main() {
    int x = 5, y = 10;
    if (x < y && x > 0) {
        cout << "Condition met" << endl;
    }
    return 0;
}

Bitwise Operators

Manipulate bits of integers.

  • &, |, ^: AND, OR, XOR
  • ~: NOT
  • <<, >>: Shift left, right
#include 
using namespace std;

int main() {
    unsigned int a = 5; // 0101
    unsigned int b = 3; // 0011
    cout << "AND: " << (a & b) << endl; // 0001
    return 0;
}

Control Flow Statements

if-else Statements

Conditional execution based on boolean expressions.

#include 
using namespace std;

int main() {
    int num = 10;
    if (num > 0) {
        cout << "Positive" << endl;
    } else if (num < 0) {
        cout << "Negative" << endl;
    } else {
        cout << "Zero" << endl;
    }
    return 0;
}

switch Statement

Multi-way branching for discrete values.

#include 
using namespace std;

int main() {
    int day = 3;
    switch (day) {
        case 1: cout << "Monday" << endl; break;
        case 3: cout << "Wednesday" << endl; break;
        default: cout << "Other day" << endl;
    }
    return 0;
}

for Loop

Iterate with explicit initialization and increment.

#include 
using namespace std;

int main() {
    for (int i = 1; i <= 5; i++) {
        cout << i << " ";
    }
    cout << endl;
    return 0;
}

while Loop

Repeat while a condition holds true.

#include 
using namespace std;

int main() {
    int i = 1;
    while (i <= 5) {
        cout << i << " ";
        i++;
    }
    cout << endl;
    return 0;
}

do-while Loop

Execute at least once, then repeat if condition is true.

#include 
using namespace std;

int main() {
    int i = 1;
    do {
        cout << i << " ";
        i++;
    } while (i <= 5);
    cout << endl;
    return 0;
}

Functions in C++

Function Basics

Functions encapsulate reusable logic with parameters and return values.

#include 
using namespace std;

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

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

Tip: Use inline functions for small, frequently called functions to improve performance.

Function Overloading

Define multiple functions with the same name but different signatures.

#include 
using namespace std;

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

int main() {
    cout << "Int sum: " << add(5, 3) << endl;
    cout << "Double sum: " << add(5.5, 3.3) << endl;
    return 0;
}

Arrays and Strings

Arrays

Store fixed-size collections of elements of the same type.

#include 
using namespace std;

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    for (int i = 0; i < 5; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;
    return 0;
}

Tip: Prefer std::array (C++11) for fixed-size arrays with bounds checking.

Strings

C++ uses std::string for dynamic string manipulation.

#include 
#include 
using namespace std;

int main() {
    string name = "Alice";
    cout << "Name: " << name << ", Length: " << name.length() << endl;
    return 0;
}

Tip: Use std::getline for reading entire lines with spaces.

Pointers and References

Pointers

Store memory addresses for direct access and manipulation.

#include 
using namespace std;

int main() {
    int x = 10;
    int* ptr = &x;
    cout << "Value: " << *ptr << ", Address: " << ptr << endl;
    return 0;
}

Tip: Always initialize pointers to avoid undefined behavior.

References

Aliases for variables, simplifying parameter passing.

#include 
using namespace std;

int main() {
    int x = 10;
    int& ref = x;
    ref = 20;
    cout << "x: " << x << endl; // 20
    return 0;
}

Object-Oriented Programming

Classes and Objects

Classes define blueprints; objects are instances.

#include 
using namespace std;

class Person {
public:
    string name;
    int age;
    void introduce() {
        cout << "Hi, I'm " << name << ", " << age << " years old." << endl;
    }
};

int main() {
    Person p;
    p.name = "Alice";
    p.age = 25;
    p.introduce();
    return 0;
}

Tip: Use private members with getters/setters for encapsulation.

Inheritance

Derived classes inherit and extend base classes.

#include 
using namespace std;

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

class Dog : public Animal {
public:
    void bark() { cout << "Woof!" << endl; }
};

int main() {
    Dog d;
    d.eat();
    d.bark();
    return 0;
}

File Handling

Writing to Files

Use ofstream to create and write to files.

#include 
#include 
using namespace std;

int main() {
    ofstream file("example.txt");
    if (file.is_open()) {
        file << "Hello, C++!" << endl;
        file.close();
    }
    return 0;
}

Reading from Files

Use ifstream to read file contents.

#include 
#include 
#include 
using namespace std;

int main() {
    ifstream file("example.txt");
    string line;
    if (file.is_open()) {
        while (getline(file, line)) {
            cout << line << endl;
        }
        file.close();
    }
    return 0;
}

Templates

Function Templates

Write generic functions for multiple data types.

#include 
using namespace std;

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

int main() {
    cout << "Int sum: " << add(5, 3) << endl;
    cout << "Double sum: " << add(5.5, 3.3) << endl;
    return 0;
}

Class Templates

Define generic classes for reusable data structures.

#include 
using namespace std;

template 
class Box {
public:
    T value;
    Box(T v) : value(v) {}
    void print() { cout << value << endl; }
};

int main() {
    Box intBox(10);
    Box doubleBox(3.14);
    intBox.print();
    doubleBox.print();
    return 0;
}

Standard Template Library (STL)

Vectors

Dynamic arrays with automatic resizing.

#include 
#include 
using namespace std;

int main() {
    vector vec = {1, 2, 3};
    vec.push_back(4);
    for (int x : vec) {
        cout << x << " ";
    }
    cout << endl;
    return 0;
}

Tip: Use reserve to preallocate memory and improve performance.

Maps

Associative containers for key-value pairs.

#include 
#include 
using namespace std;

int main() {
    map ages;
    ages["Alice"] = 25;
    ages["Bob"] = 30;
    for (auto &pair : ages) {
        cout << pair.first << ": " << pair.second << endl;
    }
    return 0;
}

Exception Handling

Try-Catch Blocks

Handle errors gracefully with try-catch.

#include 
using namespace std;

int main() {
    try {
        int x = 10, y = 0;
        if (y == 0) throw "Division by zero";
        cout << x / y << endl;
    } catch (const char* msg) {
        cout << "Error: " << msg << endl;
    }
    return 0;
}

Standard Exceptions

Use standard exception classes for robust error handling.

#include 
#include 
using namespace std;

int main() {
    try {
        throw runtime_error("An error occurred");
    } catch (const runtime_error& e) {
        cout << "Caught: " << e.what() << endl;
    }
    return 0;
}

Dynamic Memory Allocation

new Operator

Allocate memory dynamically on the heap.

#include 
using namespace std;

int main() {
    int* ptr = new int(10);
    cout << "Value: " << *ptr << endl;
    delete ptr;
    return 0;
}

Tip: Always pair new with delete to prevent memory leaks.

delete Operator

Free dynamically allocated memory.

#include 
using namespace std;

int main() {
    int* arr = new int[5];
    for (int i = 0; i < 5; i++) {
        arr[i] = i + 1;
    }
    cout << "Array: ";
    for (int i = 0; i < 5; i++) {
        cout << arr[i] << " ";
    }
    delete[] arr;
    cout << endl;
    return 0;
}

Namespaces

Organizing Code

Namespaces prevent name conflicts and organize code logically.

#include 
using namespace std;

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

namespace String {
    string add(string a, string b) { return a + b; }
}

int main() {
    cout << "Math add: " << Math::add(5, 3) << endl;
    cout << "String add: " << String::add("Hello, ", "World!") << endl;
    return 0;
}

Tip: Use using namespace std; sparingly in production to avoid namespace pollution.

Lambda Expressions

Anonymous Functions

Lambda expressions (C++11) create inline, anonymous functions for concise code.

#include 
#include 
#include 
using namespace std;

int main() {
    vector nums = {5, 2, 8, 1};
    sort(nums.begin(), nums.end(), [](int a, int b) { return a < b; });
    for (int x : nums) {
        cout << x << " ";
    }
    cout << endl;
    return 0;
}

Tip: Use capture lists (e.g., [&], [=]) to access external variables.

Smart Pointers

unique_ptr

Manages a single, non-shared resource (C++11).

#include 
#include 
using namespace std;

int main() {
    unique_ptr ptr = make_unique(10);
    cout << "Value: " << *ptr << endl;
    return 0;
}

shared_ptr

Manages shared resources with reference counting.

#include 
#include 
using namespace std;

int main() {
    shared_ptr ptr1 = make_shared(20);
    shared_ptr ptr2 = ptr1;
    cout << "Value: " << *ptr1 << ", Count: " << ptr1.use_count() << endl;
    return 0;
}

Multithreading

Basic Threads

Use std::thread for concurrent execution (C++11).

#include 
#include 
using namespace std;

void print() {
    cout << "Running in thread" << endl;
}

int main() {
    thread t(print);
    t.join();
    cout << "Main thread" << endl;
    return 0;
}

Tip: Use join or detach to manage thread lifecycle.

Try our recommended online C++ compiler:

Open Programiz C++ Compiler

Download Basic C++ Notes by Richard Grimes

View PDF Notes Download PDF Notes

C++ Programming Quiz

Test Your Knowledge

Answer these questions to solidify your C++ understanding.

1. What is the output of this code?

#include 
using namespace std;

int main() {
    int x = 5;
    cout << x++ << " " << ++x << endl;
    return 0;
}

Answer: 5 7

Explanation: x++ outputs 5 and increments to 6; ++x increments to 7 and outputs 7.

2. What does this function template do?

template 
T max(T a, T b) {
    return (a > b) ? a : b;
}

Answer: Returns the larger of two values

Explanation: Compares two values using the ternary operator to return the larger one.

3. What is wrong with this code?

#include 
using namespace std;

int main() {
    int arr[3] = {1, 2, 3};
    cout << arr[3] << endl;
    return 0;
}

Answer: Array out-of-bounds access

Explanation: arr[3] accesses an invalid index (valid: 0–2), causing undefined behavior.

4. What is the output of this inheritance code?

#include 
using namespace std;

class Base {
public:
    void show() { cout << "Base" << endl; }
};

class Derived : public Base {
public:
    void show() { cout << "Derived" << endl; }
};

int main() {
    Derived d;
    d.show();
    return 0;
}

Answer: Derived

Explanation: The Derived class overrides show, so d.show() calls the derived version.

5. What does this STL vector code print?

#include 
#include 
using namespace std;

int main() {
    vector vec = {1, 2, 3};
    vec.push_back(4);
    cout << vec.size() << endl;
    return 0;
}

Answer: 4

Explanation: The vector starts with 3 elements; push_back(4) adds a fourth.

6. What is the purpose of this smart pointer?

#include 
using namespace std;

int main() {
    unique_ptr ptr = make_unique(10);
    return 0;
}

Answer: Manages a single, non-shared resource

Explanation: unique_ptr ensures automatic memory cleanup for a single owner, preventing leaks.

7. What does this lambda expression do?

#include 
using namespace std;

int main() {
    auto lambda = [](int x) { return x * x; };
    cout << lambda(5) << endl;
    return 0;
}

Answer: 25

Explanation: The lambda computes the square of its input (5 * 5 = 25).