COURSE ยท 17 LESSONS ยท 100% FREE
๐Ÿ”ท

C++ Programming

C with classes, templates, STL, and modern features. Game engines, browsers, and operating systems use it.

0Lessons
0Code Examples
ZeroPrerequisites
0%
You've completed 0 of 17 lessons
J/โ†“ Next
K/โ†‘ Prev
Esc Collapse
/ Search
Foundations
01

Hello World & Setup

C++ adds classes, templates, and STL on top of C.

#include <iostream>
#include <string>
using namespace std;

int main() {
    cout << "Hello, World!" << endl;
    string name = "Mayank";
    cout << "Name: " << name << endl;
    return 0;
}
// Compile: g++ -std=c++17 hello.cpp -o hello
02

Variables & Types

int, float, double, char, bool, string, auto (let the compiler figure it out).

#include <iostream>
#include <string>
using namespace std;

int main() {
    int age = 15;
    double pi = 3.14159265;
    char grade = 'A';
    bool passed = true;
    string name = "Mayank";
    auto x = 42;        // int
    auto y = 3.14;      // double
    auto z = "hello";   // const char*

    cout << name << " age=" << age << endl;
    cout << "pi=" << pi << endl;
    cout << "passed=" << passed << endl;
    return 0;
}
03

References & Pointers

Reference (&) is a nickname for a variable. Pointer (*) holds an address.

#include <iostream>
using namespace std;

void modify(int &ref, int *ptr) {
    ref = 100;
    *ptr = 200;
}

int main() {
    int a = 10;
    int &r = a;   // reference
    int *p = &a;  // pointer

    cout << "a=" << a << " r=" << r << " *p=" << *p << endl;
    modify(a, p);
    cout << "a=" << a << " r=" << r << " *p=" << *p << endl;
    return 0;
}
04

Functions & Overloading

Same function name, different parameters. Default arguments. Inline functions.

#include <iostream>
using namespace std;

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

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

int main() {
    cout << add(3, 4) << endl;
    cout << add(3.14, 2.72) << endl;
    cout << add(string("Hello "), string("World")) << endl;
    cout << power(5) << endl;
    cout << power(2, 10) << endl;
    return 0;
}
05

Control Flow & Loops

if/else, switch, for, while, range-based for, structured bindings.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> nums = {10, 20, 30, 40, 50};

    // Range-based for
    for (const auto &n : nums) cout << n << " ";
    cout << endl;

    // Structured bindings (C++17)
    vector<pair<string,int>> items = {{"a",1},{"b",2},{"c",3}};
    for (const auto &[key, val] : items)
        cout << key << "=" << val << ", ";
    cout << endl;

    // if with initializer (C++17)
    if (auto it = find(nums.begin(), nums.end(), 30); it != nums.end())
        cout << "Found: " << *it << endl;

    return 0;
}
Object-Oriented
06

Classes & Objects

Blueprints for objects. Private data, public methods. Constructors build, destructors clean.

#include <iostream>
#include <string>
using namespace std;

class Dog {
private:
    string name;
    int age;
public:
    Dog(string n, int a) : name(n), age(a) {}
    ~Dog() { cout << name << " destroyed\n"; }
    void bark() const { cout << name << ": Woof! (age " << age << ")\n"; }
    string getName() const { return name; }
    void setAge(int a) { if (a > 0) age = a; }
};

int main() {
    Dog d("Rex", 5);
    d.bark();
    d.setAge(6);
    d.bark();
    return 0;
}
07

Inheritance & Polymorphism

Child classes inherit from parent. Virtual functions let child classes override behavior.

#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;

class Shape {
public:
    virtual double area() const = 0;
    virtual string type() const = 0;
    virtual ~Shape() {}
};

class Circle : public Shape {
    double r;
public:
    Circle(double r) : r(r) {}
    double area() const override { return 3.14159 * r * r; }
    string type() const override { return "Circle"; }
};

class Rect : public Shape {
    double w, h;
public:
    Rect(double w, double h) : w(w), h(h) {}
    double area() const override { return w * h; }
    string type() const override { return "Rectangle"; }
};

int main() {
    vector<unique_ptr<Shape>> shapes;
    shapes.push_back(make_unique<Circle>(5));
    shapes.push_back(make_unique<Rect>(4, 6));
    for (const auto &s : shapes)
        cout << s->type() << " area=" << s->area() << endl;
    return 0;
}
08

Templates

Write code that works with any type. The compiler generates the specific version for you.

#include <iostream>
#include <string>
using namespace std;

template <typename T>
T max_val(T a, T b) { return (a > b) ? a : b; }

template <typename T>
class Stack {
    T items[100];
    int top = -1;
public:
    void push(T v) { items[++top] = v; }
    T pop() { return items[top--]; }
    bool empty() const { return top < 0; }
};

int main() {
    cout << max_val(3, 7) << endl;
    cout << max_val(3.14, 2.72) << endl;
    cout << max_val(string("abc"), string("xyz")) << endl;

    Stack<int> s;
    s.push(10); s.push(20); s.push(30);
    while (!s.empty()) cout << s.pop() << " ";
    cout << endl;
    return 0;
}
09

Operator Overloading

Make operators work with your classes. +, ==, <<, [] โ€” you can define them all.

#include <iostream>
using namespace std;

class Vec2 {
    double x, y;
public:
    Vec2(double x=0, double y=0) : x(x), y(y) {}
    Vec2 operator+(const Vec2 &o) const { return {x+o.x, y+o.y}; }
    Vec2 operator*(double s) const { return {x*s, y*s}; }
    bool operator==(const Vec2 &o) const { return x==o.x && y==o.y; }
    friend ostream& operator<<(ostream &os, const Vec2 &v) {
        return os << "(" << v.x << "," << v.y << ")";
    }
    double& operator[](int i) { return i==0 ? x : y; }
};

int main() {
    Vec2 a(1,2), b(3,4);
    cout << "a+b=" << a+b << endl;
    cout << "a*3=" << a*3 << endl;
    cout << "a==b: " << (a==b) << endl;
    cout << "a[0]=" << a[0] << endl;
    return 0;
}
Modern C++
10

Smart Pointers

unique_ptr owns, shared_ptr shares, weak_ptr observes. No manual delete needed.

#include <iostream>
#include <memory>
using namespace std;

class Resource {
    string name;
public:
    Resource(string n) : name(n) { cout << name << " created\n"; }
    ~Resource() { cout << name << " destroyed\n"; }
    void use() { cout << name << " used\n"; }
};

int main() {
    // unique_ptr โ€” exclusive ownership
    auto up = make_unique<Resource>("Unique");
    up->use();

    // shared_ptr โ€” shared ownership
    auto sp1 = make_shared<Resource>("Shared");
    auto sp2 = sp1;  // ref count = 2
    cout << "ref count: " << sp1.use_count() << endl;
    sp1->use();
    sp2.reset();  // ref count = 1

    // weak_ptr โ€” observe without owning
    weak_ptr<Resource> wp = sp1;
    if (auto locked = wp.lock()) locked->use();

    return 0;
}
11

Move Semantics

Steal resources instead of copying. && means rvalue reference. std::move enables stealing.

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Buffer {
    int *data;
    size_t size;
public:
    Buffer(size_t s) : data(new int[s]), size(s) { cout << "alloc\n"; }
    ~Buffer() { delete[] data; }

    // Move constructor
    Buffer(Buffer &&o) noexcept : data(o.data), size(o.size) {
        o.data = nullptr; o.size = 0;
    }

    // Move assignment
    Buffer& operator=(Buffer &&o) noexcept {
        delete[] data;
        data = o.data; size = o.size;
        o.data = nullptr; o.size = 0;
        return *this;
    }
};

int main() {
    Buffer a(1024);
    Buffer b = move(a);  // a is now empty
    Buffer c(512);
    c = move(b);         // b is now empty
    return 0;
}
12

Lambda Expressions

Anonymous functions. Capture variables from surrounding scope. Used everywhere in modern C++.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int offset = 10;

    // Basic lambda
    auto add = [](int a, int b) { return a + b; };
    cout << add(3, 4) << endl;

    // Capture by value and reference
    auto inc = [offset](int x) { return x + offset; };
    cout << inc(5) << endl;

    // Mutable lambda
    int count = 0;
    auto counter = [count]() mutable { return ++count; };
    cout << counter() << " " << counter() << endl;

    // Lambda with STL
    vector<int> v = {5, 3, 1, 4, 2};
    sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
    for (int n : v) cout << n << " ";
    cout << endl;

    // Generic lambda (C++14)
    auto print = [](auto x) { cout << x << endl; };
    print(42); print(3.14); print("hi");
    return 0;
}
13

Constexpr & Concepts

Compute at compile time. Concepts constrain template parameters to specific types.

#include <iostream>
#include <concepts>
using namespace std;

// Constexpr โ€” compute at compile time
constexpr int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n-1);
}

constexpr int fib(int n) {
    if (n <= 1) return n;
    return fib(n-1) + fib(n-2);
}

// Concepts โ€” constrain templates
template <typename T>
concept Numeric = integral<T> || floating_point<T>;

template <Numeric T>
T square(T x) { return x * x; }

template <typename T>
concept Addable = requires(T a, T b) { { a + b } -> convertible_to<T>;
};

int main() {
    constexpr int f5 = factorial(5);  // computed at compile time
    cout << "5! = " << f5 << endl;
    cout << "fib(10) = " << fib(10) << endl;
    cout << square(5) << endl;
    cout << square(3.14) << endl;
    return 0;
}
STL & Advanced
14

STL Containers

vector, map, set, array, unordered_map โ€” pre-built data structures ready to use.

#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <array>
#include <unordered_map>
#include <algorithm>
using namespace std;

int main() {
    // Vector โ€” dynamic array
    vector<int> v = {3, 1, 4, 1, 5};
    v.push_back(9); v.pop_back();
    sort(v.begin(), v.end());
    for (int n : v) cout << n << " ";
    cout << endl;

    // Map โ€” sorted key-value
    map<string, int> ages = {{"Mayank",15},{"Alice",20}};
    ages["Bob"] = 12;
    for (auto &[k,v] : ages) cout << k << ":" << v << ", ";
    cout << endl;

    // Set โ€” unique sorted elements
    set<int> s = {5, 3, 1, 3, 5};
    cout << "set size: " << s.size() << endl;

    // Array โ€” fixed size
    array<int, 5> arr = {10, 20, 30, 40, 50};
    cout << "array: ";
    for (int n : arr) cout << n << " ";
    cout << endl;

    // Unordered map โ€” hash table, fast lookup
    unordered_map<string, double> prices = {{"apple",1.5},{"banana",0.75}};
    cout << "apple: $" << prices["apple"] << endl;
    return 0;
}
15

STL Algorithms

sort, find, transform, accumulate โ€” 100+ algorithms that work on any container.

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
using namespace std;

int main() {
    vector<int> v = {5, 3, 1, 4, 2, 8, 7, 6};

    sort(v.begin(), v.end());
    cout << "sorted: ";
    for (int n : v) cout << n << " ";
    cout << endl;

    sort(v.begin(), v.end(), greater<int>());
    cout << "desc: ";
    for (int n : v) cout << n << " ";
    cout << endl;

    auto it = find(v.begin(), v.end(), 4);
    if (it != v.end()) cout << "found at index: " << distance(v.begin(), it) << endl;

    int sum = accumulate(v.begin(), v.end(), 0);
    cout << "sum: " << sum << endl;

    transform(v.begin(), v.end(), v.begin(), [](int x){ return x * 2; });
    cout << "doubled: ";
    for (int n : v) cout << n << " ";
    cout << endl;

    int count = count_if(v.begin(), v.end(), [](int x){ return x > 10; });
    cout << ">10: " << count << endl;

    auto [mn, mx] = minmax_element(v.begin(), v.end());
    cout << "min=" << *mn << " max=" << *mx << endl;
    return 0;
}
16

File I/O & Streams

fstream for files, stringstream for string parsing, istream for formatted input.

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;

int main() {
    // File writing
    ofstream out("data.txt");
    out << "Hello File!" << endl;
    out << 42 << " " << 3.14 << endl;
    out.close();

    // File reading
    ifstream in("data.txt");
    string line;
    while (getline(in, line)) cout << line << endl;
    in.close();

    // String stream
    stringstream ss("10 20 30");
    int a, b, c;
    ss >> a >> b >> c;
    cout << "parsed: " << a << "," << b << "," << c << endl;

    // Build string
    stringstream build;
    build << "Score: " << 100 << " Name: " << "Mayank";
    cout << build.str() << endl;
    return 0;
}
17

Multithreading

std::thread, mutex, condition_variable โ€” run code in parallel.

#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <numeric>
using namespace std;

mutex mtx;
int shared_counter = 0;

void worker(int id) {
    for (int i = 0; i < 1000; i++) {
        lock_guard<mutex> lock(mtx);
        shared_counter++;
    }
}

void parallel_sum(const vector<int> &v, int start, int end, int &result) {
    result = accumulate(v.begin()+start, v.begin()+end, 0);
}

int main() {
    // Thread basics
    vector<thread> threads;
    for (int i = 0; i < 10; i++)
        threads.emplace_back(worker, i);
    for (auto &t : threads) t.join();
    cout << "counter: " << shared_counter << endl;

    // Parallel sum
    vector<int> data(1000);
    iota(data.begin(), data.end(), 1);
    int r1=0, r2=0;
    thread t1(parallel_sum, ref(data), 0, 500, ref(r1));
    thread t2(parallel_sum, ref(data), 500, 1000, ref(r2));
    t1.join(); t2.join();
    cout << "sum: " << r1+r2 << endl;
    return 0;
}