My Cheatsheets

Smart Pointers (std::unique_ptr, std::shared_ptr)

Instead of manually managing memory with new and delete, modern C++ uses smart pointers to prevent memory leaks.

Example: std::unique_ptr (Exclusive Ownership)

std::unique_ptr<int> ptr = std::make_unique<int>(10);
std::cout << *ptr << std::endl;  // Output: 10

Why? Prevents memory leaks by automatically freeing memory when the pointer goes out of scope.


RAII (Resource Acquisition Is Initialization)

RAII ensures that resources like files, sockets, and memory are automatically cleaned up when objects go out of scope.

Example: Automatic File Handling

std::ofstream file("test.txt");  // Opens file
if (file.is_open()) {
    file << "Hello, RAII!";
}  // File automatically closed when it goes out of scope

Why? Prevents resource leaks by binding resource management to object lifetime.


Move Semantics (std::move)

Avoid expensive deep copies by transferring ownership of resources.

Example: Moving a Vector

std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = std::move(v1);  // Transfers ownership
std::cout << v1.size() << std::endl;  // Output: 0 (v1 is now empty)

Why? Avoids unnecessary copying, improving performance.


constexpr (Compile-Time Evaluation)

Allows functions to compute values at compile-time, reducing runtime overhead.

Example: Compile-Time Fibonacci


constexpr int fibonacci(int n) {
    return (n <= 1) ? n : fibonacci(n - 1) + fibonacci(n - 2);
}
std::cout << fibonacci(10) << std::endl;  // Computed at compile-time

Why? Optimizes performance by eliminating runtime calculations.


Multithreading (std::thread)

Run tasks in parallel with std::thread.

Example: Creating a Thread

std::thread t([]() { std::cout << "Hello from a thread!" << std::endl; });
t.join();  // Waits for the thread to finish

Why? Enables parallel execution without third-party libraries.


std::async (Asynchronous Execution)

Instead of manually managing threads, std::async allows you to run tasks asynchronously.

Example: Asynchronous Task Execution

std::future<int> result = std::async([]() { return 42; });
std::cout << result.get() << std::endl;  // Output: 42

Why? Simplifies concurrency and manages threads automatically.


Ranges (std::ranges)

Introduced in C++20, ranges simplify working with collections.

Example: Filtering a List

for (int n : numbers | std::views::filter([](int x) { return x % 2 == 0; })) {
    std::cout << n << " ";  // Output: 2 4
}

Why? More readable and eliminates unnecessary loops.


std::variant (Type-Safe Alternative to union)

Allows storing multiple types safely.

Example: Holding Different Types

std::variant<int, std::string> data;
data = 42;
std::cout << std::get<int>(data) << std::endl;  // Output: 42

Why? Avoids unsafe type punning and ensures type safety.


std::filesystem (C++17 Standardized File Operations)

Instead of using platform-specific file handling, std::filesystem provides a modern solution.

Example: Checking File Existence

std::filesystem::path p{"test.txt"};
if (std::filesystem::exists(p)) {
    std::cout << "File exists!" << std::endl;
}

Why? Cross-platform and removes dependency on third-party libraries.


Pattern Matching (std::visit)

Use std::visit for safe variant handling, replacing if-else chains.

Example: Pattern Matching on std::variant

std::visit([](auto&& value) { std::cout << value << std::endl; }, data);

Why? More readable and eliminates unsafe type handling.


Summary

Feature Why It's Useful
Smart Pointers (unique_ptr, shared_ptr) Automatic memory management
RAII Ensures resources are cleaned up
Move Semantics (std::move) Avoids unnecessary copies
constexpr Enables compile-time computation
Multithreading (std::thread) Runs tasks in parallel
Asynchronous Tasks (std::async) Simplifies concurrency
Ranges (std::ranges) Simplifies collection operations
std::variant Safer alternative to union
std::filesystem Standardized file operations
Pattern Matching (std::visit) Type-safe handling of std::variant

** Next Steps**

  1. Start with smart pointers (std::unique_ptr, std::shared_ptr).
  2. Understand move semantics (std::move).
  3. Learn about concurrency (std::thread, std::async).
  4. Try ranges and filesystem operations.