C++ Tutorial


Beginners To Experts


The site is under development.

C++ Tutorial

1.1 What is C++?
C++ is a powerful general-purpose programming language. It supports procedural, object-oriented, and generic programming, and is widely used for system/software development and game engines.
<!-- Example -->
<pre>
#include <iostream>
using namespace std;

int main() {
    cout << "Hello, C++!" << endl;
    return 0;
}
</pre>
      


1.2 History of C++
C++ was developed by Bjarne Stroustrup in the early 1980s at Bell Labs as an extension to the C language. It introduced classes and objects to support OOP.

1.3 Features of C++
- Object-oriented
- Fast performance
- Low-level memory manipulation
- Rich library support

1.4 Setting Up the Environment
Install an IDE like Code::Blocks or Visual Studio. Alternatively, you can use command-line compilers like `g++`.

1.5 Your First C++ Program
Below is a simple program that prints a greeting message:
<pre>
#include <iostream>

int main() {
    std::cout << "Welcome to C++!" << std::endl;
    return 0;
}
</pre>
      


1.6 Understanding the Structure
- `#include <iostream>` imports the input-output stream
- `main()` is the entry point
- `cout` outputs text to the console

1.7 Compiling and Running Code
Use `g++ file.cpp -o output` to compile and `./output` to run.

1.8 Comments in C++
Comments help explain code:
<pre>
// This is a single-line comment
/* This is
   a multi-line comment */
</pre>
      


1.9 C++ vs C
C++ supports classes, objects, function overloading, and exception handling—features that C does not have.

1.10 Best Practices
- Use meaningful variable names
- Comment your code
- Use consistent indentation

2.1 What Are Variables?
Variables are containers for storing data values. In C++, variables must be declared with a data type before use.
<pre>
int age = 25;
float weight = 70.5;
char grade = 'A';
</pre>
      


2.2 Basic Data Types
- `int`: integer numbers
- `float`: decimal numbers
- `double`: larger decimal numbers
- `char`: single character
- `bool`: true/false

2.3 Variable Declaration and Initialization
You can declare variables with or without initialization.
<pre>
int x;          // Declaration
x = 10;         // Initialization
int y = 20;     // Declaration with initialization
</pre>
      


2.4 Constants in C++
Constants are fixed values that cannot be changed during program execution. Use `const` keyword.
<pre>
const float PI = 3.14;
</pre>
      


2.5 Type Conversion
Implicit and explicit conversion changes one data type to another.
<pre>
int a = 5;
float b = a;      // Implicit conversion
int c = (int)3.7; // Explicit conversion (type casting)
</pre>
      


2.6 Scope of Variables
Scope defines the visibility and lifetime of a variable. Variables can be global or local.
<pre>
int globalVar = 100;

void show() {
    int localVar = 50;
}
</pre>
      


2.7 Global vs Local Variables
- Global: Declared outside all functions
- Local: Declared inside a function or block

2.8 Auto Keyword
Automatically deduces the type of variable (C++11 and later).
<pre>
auto num = 42;      // Treated as int
auto name = "Tom";  // Treated as const char*
</pre>
      


2.9 Data Type Sizes
Sizes vary by system and compiler, but commonly:
- `int`: 4 bytes
- `float`: 4 bytes
- `double`: 8 bytes
- `char`: 1 byte
Use `sizeof()` to check size.
<pre>
cout << sizeof(int);     // Outputs 4
cout << sizeof(double);  // Outputs 8
</pre>
      


2.10 Best Practices with Variables
- Use descriptive names
- Avoid global variables when possible
- Initialize variables before use

3.1 Introduction to Operators
Operators perform operations on variables and values. For example, `+` is used to add two numbers.
<pre>
int x = 10;
int y = 5;
int result = x + y;
cout << result; // Output: 15
</pre>
      


3.2 Arithmetic Operators
These include: `+`, `-`, `*`, `/`, `%` for addition, subtraction, multiplication, division, and modulo.
<pre>
int a = 20;
int b = 6;
cout << a / b; // Output: 3
cout << a % b; // Output: 2
</pre>
      


3.3 Assignment Operators
These are used to assign values: `=`, `+=`, `-=`, `*=`, `/=`, `%=`.
<pre>
int a = 5;
a += 10; // Equivalent to a = a + 10;
cout << a; // Output: 15
</pre>
      


3.4 Relational Operators
Used to compare values: `==`, `!=`, `>`, `<`, `>=`, `<=`.
<pre>
int x = 5, y = 10;
cout << (x < y); // Output: 1 (true)
</pre>
      


3.5 Logical Operators
Used to combine multiple conditions: `&&`, `||`, `!`.
<pre>
int a = 5;
int b = 10;
bool result = (a < b) && (b > 0); // true
</pre>
      


3.6 Increment and Decrement
Used to increase or decrease values: `++`, `--`.
<pre>
int a = 3;
a++; // a becomes 4
--a; // a becomes 3 again
</pre>
      


3.7 Conditional (Ternary) Operator
Short form of `if-else`: `condition ? true_value : false_value;`
<pre>
int x = 8;
int y = (x > 5) ? 100 : 0;
cout << y; // Output: 100
</pre>
      


3.8 Bitwise Operators
Operate at the bit level: `&`, `|`, `^`, `~`, `<<`, `>>`.
<pre>
int a = 6;   // 0110
int b = 3;   // 0011
cout << (a & b); // Output: 2 (0001)
</pre>
      


3.9 Operator Precedence
Determines which operators are evaluated first. Parentheses can change default precedence.
<pre>
int result = 10 + 2 * 3;       // 16
int fixed = (10 + 2) * 3;      // 36
</pre>
      


3.10 Expressions
An expression combines variables and operators to produce a value.
<pre>
int a = 5;
int b = 10;
int sum = a + b; // Expression: a + b
</pre>
      

4.1 Introduction to Control Flow
Control flow statements direct the order of execution in a program. They include conditionals and loops.
<pre>
int x = 10;
if (x > 5) {
  cout << "x is greater than 5";
}
</pre>
      


4.2 if Statement
Executes a block of code if a specified condition is true.
<pre>
int score = 90;
if (score >= 80) {
  cout << "Excellent!";
}
</pre>
      


4.3 if-else Statement
Executes one block if true, another if false.
<pre>
int num = 3;
if (num % 2 == 0) {
  cout << "Even";
} else {
  cout << "Odd";
}
</pre>
      


4.4 else-if Ladder
Used to test multiple conditions.
<pre>
int marks = 75;
if (marks >= 90) {
  cout << "A";
} else if (marks >= 75) {
  cout << "B";
} else {
  cout << "C";
}
</pre>
      


4.5 switch Statement
Selects from multiple blocks using a `case` value.
<pre>
int day = 2;
switch(day) {
  case 1: cout << "Monday"; break;
  case 2: cout << "Tuesday"; break;
  default: cout << "Other Day";
}
</pre>
      


4.6 while Loop
Repeats a block while the condition is true.
<pre>
int i = 1;
while (i <= 3) {
  cout << i << " ";
  i++;
}
</pre>
      


4.7 do-while Loop
Executes the loop at least once, then checks the condition.
<pre>
int i = 1;
do {
  cout << i << " ";
  i++;
} while (i <= 3);
</pre>
      


4.8 for Loop
A concise loop with initializer, condition, and increment.
<pre>
for (int i = 1; i <= 5; i++) {
  cout << i << " ";
}
</pre>
      


4.9 break Statement
Immediately exits the current loop or `switch` block.
<pre>
for (int i = 1; i <= 5; i++) {
  if (i == 3) break;
  cout << i << " ";
}
</pre>
      


4.10 continue Statement
Skips the rest of the loop body for current iteration.
<pre>
for (int i = 1; i <= 5; i++) {
  if (i == 3) continue;
  cout << i << " ";
}
</pre>
      

5.1 Introduction to Functions
Functions are blocks of reusable code that perform specific tasks. They help organize and modularize code.
#include <iostream>
using namespace std;

void greet() {
    cout << "Hello from a function!" << endl;
}

      


5.2 Defining and Calling Functions
A function is defined with a return type, name, and parameters. Call it using its name.
#include <iostream>
using namespace std;

void sayHello() {
    cout << "Hello!" << endl;
}

int main() {
    sayHello();  // function call
    return 0;
}
      


5.3 Function Parameters
Functions can take input using parameters (arguments).
void greetUser(string name) {
    cout << "Welcome, " << name << "!" << endl;
}
      


5.4 Return Values
Functions can return a value using the `return` keyword.
int add(int a, int b) {
    return a + b;
}
      


5.5 Function Prototypes
Prototypes declare the function before defining it. Useful when functions are defined after `main()`.
void greet(); // prototype

int main() {
    greet();
    return 0;
}

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


5.6 Inline Functions
Inline functions are small functions defined with `inline` keyword to reduce function-call overhead.
inline int square(int x) {
    return x * x;
}
      


5.7 Default Arguments
Functions can have default values for parameters.
void greet(string name = "Guest") {
    cout << "Hello, " << name << endl;
}
      


5.8 Function Overloading
You can define multiple functions with the same name but different parameter lists.
void show(int x) {
    cout << "Integer: " << x << endl;
}

void show(string text) {
    cout << "String: " << text << endl;
}
      


5.9 Recursion
A function that calls itself is called recursive. Useful for problems like factorial, Fibonacci, etc.
int factorial(int n) {
    if (n == 0) return 1;
    return n * factorial(n - 1);
}
      


5.10 Scope and Lifetime of Functions
- Local variables exist only inside the function
- Global variables exist throughout the program
int globalVar = 100;

void demo() {
    int localVar = 50;
    cout << localVar << " " << globalVar;
}
      

6.1 Introduction to Arrays
An array is a collection of elements of the same type stored in contiguous memory locations.
int numbers[5] = {1, 2, 3, 4, 5};
cout << numbers[0]; // Output: 1
      


6.2 Declaring and Initializing Arrays
Arrays can be declared and initialized either together or separately.
int data[3];
data[0] = 10;
data[1] = 20;
data[2] = 30;
      


6.3 Accessing Array Elements
Access array elements using an index, starting from 0.
int scores[] = {80, 90, 100};
cout << scores[1]; // Output: 90
      


6.4 Looping Through Arrays
You can loop through arrays using `for` or `while` loops.
int nums[] = {5, 10, 15, 20};
for (int i = 0; i < 4; i++) {
    cout << nums[i] << " ";
}
      


6.5 Multidimensional Arrays
These are arrays with more than one index, like matrices.
int matrix[2][3] = {
    {1, 2, 3},
    {4, 5, 6}
};
cout << matrix[1][2]; // Output: 6
      


6.6 Array Functions
You can pass arrays to functions and iterate inside them.
void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        cout << arr[i] << " ";
    }
}
      


6.7 Introduction to Strings
C++ offers both C-style strings (`char[]`) and the `string` class.
#include 
string name = "Alice";
cout << name;
      


6.8 C-Style Strings
Traditional strings are arrays of characters ending with a null character (`\0`).
char name[] = "Bob";
cout << name; // Output: Bob
      


6.9 String Functions
Functions like `.length()`, `.substr()`, `.append()`, `.find()` are available for C++ strings.
string word = "Hello";
cout << word.length(); // Output: 5
      


6.10 Comparing Strings
Strings can be compared using `==`, or functions like `.compare()`.
string a = "apple";
string b = "banana";
if (a < b) {
    cout << "apple comes first";
}
      

7.1 Introduction to OOP
Object-Oriented Programming is a paradigm that uses "objects" — instances of "classes" — to structure code.
class Car {
public:
    string model;
};
      


7.2 Classes and Objects
A class is a blueprint; an object is an instance of that class.
class Animal {
public:
    string name;
};

int main() {
    Animal dog;
    dog.name = "Buddy";
    cout << dog.name;
}
      


7.3 Access Specifiers
`public`, `private`, and `protected` control access to class members.
class Box {
private:
    int length;
public:
    void setLength(int l) {
        length = l;
    }
};
      


7.4 Constructors
Constructors are special methods called when an object is created.
class Person {
public:
    Person() {
        cout << "Constructor called!";
    }
};
      


7.5 Destructors
Destructors clean up when objects go out of scope. Use `~ClassName()`.
class Person {
public:
    ~Person() {
        cout << "Destructor called!";
    }
};
      


7.6 Member Functions
Functions defined inside a class are called member functions.
class Circle {
public:
    void draw() {
        cout << "Drawing circle";
    }
};
      


7.7 Object Initialization
Objects can be initialized using constructors or manually by setting attributes.
class Book {
public:
    string title;
};

int main() {
    Book b;
    b.title = "C++ Guide";
    cout << b.title;
}
      


7.8 Encapsulation
Encapsulation hides internal details using `private` access and exposes only necessary parts using `public`.
class BankAccount {
private:
    int balance;
public:
    void setBalance(int b) {
        balance = b;
    }
    int getBalance() {
        return balance;
    }
};
      


7.9 Abstraction
Abstraction shows only essential details while hiding complex implementation.
class Remote {
public:
    void powerOn() {
        cout << "Power ON";
    }
};
      


7.10 Real-World Example
OOP can model real-world objects like cars, employees, or students.
class Student {
public:
    string name;
    int age;

    void display() {
        cout << name << " is " << age << " years old.";
    }
};
      

8.1 What is Inheritance?
Inheritance allows a class (child) to acquire properties of another class (parent).
class Vehicle {
public:
    void move() {
        cout << "Moving...";
    }
};

class Car : public Vehicle {
};
      


8.2 Types of Inheritance
- Single
- Multiple
- Multilevel
- Hierarchical
- Hybrid
class A { };
class B : public A { };  // Single inheritance
      


8.3 Single Inheritance
One base class and one derived class.
class Animal {
public:
    void speak() {
        cout << "Animal speaks";
    }
};

class Dog : public Animal {
};
      


8.4 Multilevel Inheritance
A class inherits from another derived class.
class A { };
class B : public A { };
class C : public B { };
      


8.5 Multiple Inheritance
A class inherits from more than one base class.
class A { };
class B { };
class C : public A, public B { };
      


8.6 Hierarchical Inheritance
Multiple classes inherit from one base class.
class Parent { };
class Child1 : public Parent { };
class Child2 : public Parent { };
      


8.7 Hybrid Inheritance
Combination of more than one type of inheritance.
class A { };
class B : public A { };
class C { };
class D : public B, public C { };
      


8.8 Accessing Base Class Members
Use object of child class to access public members of base class.
Dog d;
d.speak();  // Inherited from Animal
      


8.9 Constructors in Inheritance
Base class constructor is called before derived class constructor.
class Base {
public:
    Base() {
        cout << "Base constructor";
    }
};

class Derived : public Base {
public:
    Derived() {
        cout << "Derived constructor";
    }
};
      


8.10 Overriding Functions
Derived class can override base class methods.
class A {
public:
    void show() {
        cout << "Base";
    }
};

class B : public A {
public:
    void show() {
        cout << "Derived";
    }
};
      

9.1 What is Polymorphism?
Polymorphism means "many forms". In C++, it allows methods to behave differently depending on the object.
class Shape {
public:
    void draw() {
        cout << "Drawing shape";
    }
};
      


9.2 Compile-time Polymorphism
Achieved through function overloading and operator overloading.
void print(int x) {
    cout << "Int: " << x;
}

void print(string s) {
    cout << "String: " << s;
}
      


9.3 Function Overloading
Multiple functions with the same name but different parameters.
int add(int a, int b) {
    return a + b;
}

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


9.4 Operator Overloading
Redefines how operators work with objects.
class Point {
public:
    int x;
    Point operator+(Point p) {
        Point temp;
        temp.x = x + p.x;
        return temp;
    }
};
      


9.5 Runtime Polymorphism
Achieved through inheritance and virtual functions.
class Base {
public:
    virtual void show() {
        cout << "Base";
    }
};
      


9.6 Virtual Functions
Functions in base class that can be overridden in derived class.
class Derived : public Base {
public:
    void show() override {
        cout << "Derived";
    }
};
      


9.7 Abstract Classes
A class with at least one pure virtual function.
class Animal {
public:
    virtual void sound() = 0; // Pure virtual
};
      


9.8 Interfaces
Abstract classes serve as interfaces in C++.
class IPrintable {
public:
    virtual void print() = 0;
};
      


9.9 Function Pointers
Functions can be pointed to and invoked via pointers.
void hello() {
    cout << "Hi!";
}

int main() {
    void (*ptr)() = hello;
    ptr(); // Call via pointer
}
      


9.10 Vtables and Vptr
Used internally by C++ to support runtime polymorphism.
// Automatically managed by compiler, not directly used in code
      

10.1 Introduction to File Handling
File handling allows reading from and writing to files.
#include 
using namespace std;
      


10.2 Opening Files
Use `ifstream` for reading, `ofstream` for writing.
ofstream file("example.txt");
file << "Hello File!";
file.close();
      


10.3 Writing to Files
Write using `ofstream` and `<<` operator.
ofstream file("data.txt");
file << "This is a test.";
file.close();
      


10.4 Reading from Files
Read using `ifstream` and `>>` or `getline()`.
ifstream file("data.txt");
string text;
while (file >> text) {
    cout << text << " ";
}
file.close();
      


10.5 getline() Function
Reads a full line including spaces.
ifstream file("story.txt");
string line;
getline(file, line);
cout << line;
      


10.6 Checking File Status
Use `is_open()`, `eof()` to check file state.
ifstream file("log.txt");
if (file.is_open()) {
    cout << "Opened!";
}
      


10.7 Appending to Files
Open file in append mode using `ios::app`.
ofstream file("data.txt", ios::app);
file << "\nNew entry";
file.close();
      


10.8 File Modes
Modes include `ios::in`, `ios::out`, `ios::app`, `ios::binary`, etc.
ofstream file("log.txt", ios::out | ios::app);
      


10.9 Reading Characters
Use `.get()` or `.get(char)` to read char-by-char.
char ch;
file.get(ch);
cout << ch;
      


10.10 Closing Files
Always close files using `.close()`.
file.close();
      

11.1 Introduction to Templates
Templates allow writing generic and reusable code for functions and classes.
template <typename T>
T add(T a, T b) {
    return a + b;
}
      


11.2 Function Templates
Define functions that work with any data type.
template <class T>
T max(T a, T b) {
    return (a > b) ? a : b;
}
      


11.3 Class Templates
Define classes that operate with generic types.
template <class T>
class Box {
public:
    T value;
};
      


11.4 Template Specialization
Customize template behavior for specific types.
template <>
class Box<int> {
public:
    int value;
    void show() {
        cout << "Int Box";
    }
};
      


11.5 Non-type Template Parameters
Templates can take values (like integers) as parameters.
template <int size>
class Array {
    int arr[size];
};
      


11.6 Template Arguments Deduction
Compiler deduces template types from arguments.
auto result = add(5, 10); // T is int
      


11.7 Variadic Templates
Templates that take variable number of parameters.
template <typename T, typename... Args>
void func(T first, Args... args) {
    cout << first << endl;
    func(args...);
}
      


11.8 Template Template Parameters
Templates that take other templates as parameters.
template <template <typename> class Container, typename T>
class Wrapper {
    Container<T> c;
};
      


11.9 Advantages of Templates
Code reusability and type safety.

11.10 Limitations of Templates
Complex errors and increased compile time.

12.1 Introduction to Exceptions
Exceptions are runtime errors that can be caught and handled.
try {
    // code that may throw exception
}
catch (exception &e) {
    cout << e.what();
}
      


12.2 Throwing Exceptions
Use `throw` keyword to raise an exception.
throw runtime_error("Error occurred");
      


12.3 Catching Exceptions
Catch exceptions using `catch` blocks.
try {
    // code
} catch (int e) {
    cout << "Int exception: " << e;
}
      


12.4 Multiple Catch Blocks
Handle different exceptions separately.
try {
    // code
} catch (int e) {
    // handle int exception
} catch (runtime_error &e) {
    // handle runtime_error
}
      


12.5 Catch All Handler
Catch any exception using `catch(...)`.
try {
    // code
} catch (...) {
    cout << "Unknown exception";
}
      


12.6 Standard Exception Classes
Includes `logic_error`, `runtime_error`, etc.
throw logic_error("Logic error");
      


12.7 Custom Exception Classes
Derive your own exception classes.
class MyException : public exception {
public:
    const char* what() const noexcept override {
        return "My custom exception";
    }
};
      


12.8 Exception Specification
Deprecated in C++11; used to declare thrown exceptions.

12.9 Stack Unwinding
Process of cleaning up during exception propagation.

12.10 Best Practices
Use exceptions for exceptional cases only, not for regular flow.

13.1 Introduction to STL
STL is a powerful library of containers, iterators, algorithms, and functions.
#include <vector>
using namespace std;
      


13.2 Containers
Store data in structures like `vector`, `list`, `map`.
vector<int> nums = {1, 2, 3, 4};
      


13.3 Iterators
Objects that point to container elements.
vector<int> :: iterator it = nums.begin();
cout << *it;
      


13.4 Algorithms
Functions like `sort()`, `find()`, `reverse()`, etc.
sort(nums.begin(), nums.end());
      


13.5 Sequence Containers
Include `vector`, `deque`, `list`.

13.6 Associative Containers
Include `set`, `map`, `multimap`.

13.7 Unordered Containers
Include `unordered_map`, `unordered_set`.

13.8 Function Objects (Functors)
Objects that can be called like functions.
struct Compare {
    bool operator()(int a, int b) {
        return a > b;
    }
};
      


13.9 Lambda Expressions
Anonymous functions for short code.
auto add = [](int a, int b) { return a + b; };
cout << add(2, 3);
      


13.10 STL Advantages
Reusability, efficiency, and flexibility.

14.1 Introduction to Smart Pointers
Smart pointers automate memory management to avoid leaks.
#include <memory>
using namespace std;
      


14.2 unique_ptr
Owns sole ownership of an object.
unique_ptr<int> p1(new int(5));
cout << *p1;
      


14.3 shared_ptr
Shared ownership, reference counting.
shared_ptr<int> p2 = make_shared<int>(10);
      


14.4 weak_ptr
Non-owning reference to shared_ptr.

14.5 Advantages of Smart Pointers
Automatic deallocation, safer code.

14.6 Reset and Release
Reset replaces the owned pointer, release releases ownership.

14.7 Custom Deleters
Define how resources are freed.
unique_ptr<FILE, decltype(&fclose)> fp(fopen("file.txt", "r"), &fclose);
      


14.8 make_shared and make_unique
Preferred ways to create smart pointers.

14.9 Circular References
Can cause memory leaks with shared_ptr.

14.10 Best Practices
Prefer smart pointers over raw pointers.

15.1 Introduction to Multithreading
Multithreading allows concurrent execution of multiple threads.
#include <thread>
using namespace std;
      


15.2 Creating Threads
Create threads using `thread` class.
void task() {
    cout << "Thread running";
}

int main() {
    thread t(task);
    t.join();
}
      


15.3 Thread Lifecycle
New, runnable, blocked, terminated states.

15.4 Passing Arguments to Threads
Pass parameters when creating threads.
void printNum(int n) {
    cout << n;
}

thread t(printNum, 5);
      


15.5 Mutex and Lock
Used to prevent data races.
#include <mutex>
mutex mtx;
mtx.lock();
// critical section
mtx.unlock();
      


15.6 Condition Variables
Synchronize threads with conditions.

15.7 Thread Safety
Writing code safe for concurrent use.

15.8 Futures and Promises
For asynchronous results.

15.9 Detaching Threads
Run thread independently.

15.10 Best Practices
Avoid deadlocks and race conditions.

16.1 Introduction to Lambdas
Lambdas are anonymous inline functions.
auto add = [](int a, int b) { return a + b; };
cout << add(2, 3); // Output: 5
      


16.2 Lambda Syntax
Capture list, parameters, body.
[&] (int x) { cout << x; };
      


16.3 Capturing Variables
Capture by value `[=]` or by reference `[&]`.
int n = 5;
auto f = [n]() { cout << n; };
      


16.4 Mutable Lambdas
Modify captured variables by making lambda mutable.
int x = 10;
auto f = [x]() mutable { x++; cout << x; };
      


16.5 Lambda Return Types
Specify return type with `->`.
auto f = [](int x) -> double { return x / 2.0; };
      


16.6 Using Lambdas with STL
Pass lambdas to algorithms.
vector<int> v = {1, 2, 3};
sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
      


16.7 Functional Programming Concepts
Immutability, pure functions.

16.8 std::function
Wrapper for callable objects.
#include <functional>
std::function<int(int, int)> func = add;
      


16.9 Currying and Partial Application
Fix some arguments to create new functions.

16.10 Benefits of Functional Style
Easier debugging, concurrency-safe.

17.1 Introduction to Move Semantics
Move semantics optimize resource management by transferring ownership.
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = std::move(v1);
      


17.2 Rvalue References
Introduced with `&&`, bind to temporary objects.
void func(std::string&& s) {
    cout << s;
}
      


17.3 Lvalue vs Rvalue
Lvalues have a name; rvalues are temporary.

17.4 Move Constructor
Transfers resources instead of copying.
class MyClass {
public:
    MyClass(MyClass&& other) {
        // move resources
    }
};
      


17.5 Move Assignment Operator
Moves resources during assignment.
MyClass& operator=(MyClass&& other) {
    // move resources
    return *this;
}
      


17.6 std::move
Casts to rvalue reference to enable move.
std::string s1 = "Hello";
std::string s2 = std::move(s1);
      


17.7 Benefits of Move Semantics
Efficiency and performance improvement.

17.8 Perfect Forwarding
Forward arguments preserving their value category.

17.9 std::forward
Used with templates to forward arguments.

17.10 Rule of Five
If you define destructor, copy/move constructor, or copy/move assignment operator, define all.

18.1 What are Namespaces?
Namespaces prevent name conflicts by grouping code.
namespace MyNamespace {
    int x;
}
      


18.2 Using Namespace
Use `using` directive to avoid prefixing.
using namespace std;
cout << "Hello";
      


18.3 Nested Namespaces
Namespaces can be nested.
namespace A {
    namespace B {
        int y;
    }
}
      


18.4 Scope Resolution Operator
Access members with `::`.
MyNamespace::x = 10;
      


18.5 Anonymous Namespaces
For internal linkage within a file.
namespace {
    int secret;
}
      


18.6 Global vs Local Scope
Variables can have global or local scope.

18.7 Static Variables
Retain value between function calls.
void func() {
    static int count = 0;
    count++;
}
      


18.8 Extern Keyword
Declare variables defined elsewhere.
extern int globalVar;
      


18.9 Using Declarations
Bring specific names into scope.
using std::cout;
      


18.10 Best Practices
Avoid polluting global namespace.

19.1 Introduction to Dynamic Memory
Allocating memory at runtime using pointers.
int* p = new int(5);
      


19.2 Using `new` Operator
Allocates memory from the heap.
int* arr = new int[10];
      


19.3 Using `delete` Operator
Frees allocated memory.
delete p;
delete[] arr;
      


19.4 Dangling Pointers
Pointers pointing to freed memory — dangerous.

19.5 Memory Leaks
When allocated memory is not freed.

19.6 Smart Pointers Overview
Safer alternative to raw pointers.

19.7 Allocators
Custom memory management tools.

19.8 Pointer Arithmetic
Navigating arrays with pointers.
int* p = arr;
p++;
      


19.9 Best Practices
Always match `new` with `delete`.

19.10 Debugging Memory Issues
Tools like Valgrind help detect leaks.

20.1 C++11 and Later Features
New features like auto, nullptr, ranged-for.
auto x = 10;
nullptr;
for (auto &item : container) { }
      


20.2 constexpr and consteval
Compile-time computation.
constexpr int square(int x) {
    return x * x;
}
      


20.3 RAII (Resource Acquisition Is Initialization)
Manage resources using object lifetime.

20.4 Design Patterns
Common solutions like Singleton, Factory.

20.5 Code Optimization Tips
Inline functions, loop unrolling, etc.

20.6 Effective Use of Const
Mark variables and functions const when possible.

20.7 Exception Safety
Writing robust code to handle exceptions.

20.8 Coding Standards and Style
Consistency, readability, and documentation.

20.9 Testing and Debugging
Unit tests and debugging tools.

20.10 Continuous Learning
Keep updated with evolving C++ standards.

21.1 Move Constructor Basics
Transfers ownership of resources instead of copying.
class MyClass {
public:
    MyClass(MyClass&& other) noexcept {
        // move resources
    }
};
      


21.2 Move Assignment Operator
Assigns resources from an rvalue object.
MyClass& operator=(MyClass&& other) noexcept {
    if (this != &other) {
        // release current resources
        // acquire other's resources
    }
    return *this;
}
      


21.3 noexcept Specifier
Indicates the function won't throw exceptions.

21.4 Using std::move
Converts lvalues to rvalues to enable move semantics.
std::string s1 = "Hello";
std::string s2 = std::move(s1);
      


21.5 Rule of Five
Define destructor, copy/move constructors and assignments if managing resources.

21.6 Benefits of Move Semantics
Improves performance by eliminating unnecessary copying.

21.7 Move Semantics with STL
STL containers use move semantics for efficiency.

21.8 Self-move Assignment
Guard against self-move assignment.

21.9 Debugging Move Issues
Use tools and logging to track resource ownership.

21.10 Practical Examples
Write classes with move constructors and assignments.

22.1 What is Constexpr?
Indicates expressions are evaluated at compile-time.
constexpr int square(int x) {
    return x * x;
}
      


22.2 Constexpr Variables
Variables initialized at compile-time.
constexpr int size = 10;
int arr[size];
      


22.3 Constexpr Functions
Functions evaluated at compile-time when possible.

22.4 Consteval (C++20)
Functions that must be evaluated at compile-time.

22.5 Constexpr Constructors
Allows object creation at compile-time.

22.6 Limitations of Constexpr
Only allows certain operations.

22.7 Using Constexpr with STL
Some STL features support constexpr.

22.8 Benefits of Compile-time Computation
Improves performance and safety.

22.9 Examples and Use Cases
Compile-time math, array sizes, etc.

22.10 Best Practices
Use constexpr to improve efficiency.

23.1 Introduction to Modules
Modules provide better code organization and faster builds.

23.2 Module Declaration
Use `module` keyword.
export module MyModule;
      


23.3 Importing Modules
Use `import` to use other modules.
import MyModule;
      


23.4 Module Interface vs Implementation
Interface exports symbols; implementation contains code.

23.5 Benefits over Headers
Avoids multiple inclusion and speeds compilation.

23.6 Module Partitions
Split modules into parts.

23.7 Compatibility
Supported in C++20 and later.

23.8 Limitations
Toolchain support is evolving.

23.9 Using Modules in Projects
Configure build systems accordingly.

23.10 Best Practices
Gradually adopt modules for better modularity.

24.1 constexpr if (C++17)
Compile-time conditional statements.
template <typename T>
void func(T t) {
    if constexpr (std::is_integral_v<T>) {
        cout << "Integral";
    } else {
        cout << "Not integral";
    }
}
      


24.2 Introduction to Concepts (C++20)
Constraints for template parameters.

24.3 Defining Concepts
Use `concept` keyword.
template <typename T>
concept Integral = std::is_integral_v<T>;
      


24.4 Using Concepts in Templates
template <Integral T>
void func(T t) {
    // ...
}
      


24.5 Benefits of Concepts
Improved template error messages and constraints.

24.6 Combining Concepts
Use logical operators.

24.7 Standard Concepts Library
Concepts like `std::same_as`, `std::derived_from`.

24.8 Concepts vs SFINAE
Cleaner and more readable.

24.9 Practical Examples
Constrain template functions and classes.

24.10 Best Practices
Use concepts to write safer templates.

25.1 What are Coroutines?
Functions that can suspend and resume execution.

25.2 Coroutine Syntax
Use `co_await`, `co_yield`, and `co_return`.

25.3 Coroutine Promise and Handle
Mechanisms to manage coroutine state.

25.4 Benefits of Coroutines
Efficient asynchronous programming.

25.5 Basic Coroutine Example
// Example requires C++20 support
std::generator<int> counter() {
    for (int i = 0; i < 10; ++i)
        co_yield i;
}
      


25.6 Coroutine Types
Generators, tasks, and resumables.

25.7 Coroutine Libraries
Support in libraries like cppcoro.

25.8 Error Handling in Coroutines
Using exceptions with coroutines.

25.9 Coroutine Performance
Lightweight and efficient.

25.10 Practical Use Cases
Async IO, pipelines, UI programming.

26.1 What are Type Traits?
Compile-time information about types.

26.2 Using <type_traits>
Library providing traits templates.

26.3 Common Traits
`std::is_integral`, `std::is_floating_point`, etc.

26.4 Conditional Types
`std::conditional` selects types conditionally.

26.5 Removing Qualifiers
`std::remove_const`, `std::remove_reference`.

26.6 Checking Convertible Types
`std::is_convertible`.

26.7 Using Traits in Templates
Enable/disable functions based on traits.

26.8 Custom Type Traits
Defining your own traits.

26.9 SFINAE and Type Traits
Substitution failure to enable overloads.

26.10 Practical Examples
Write safer and flexible templates.

27.1 What is Template Metaprogramming?
Programming at compile time using templates.

27.2 Recursive Templates
Use recursion to compute values.
template <int N>
struct Factorial {
    static constexpr int value = N * Factorial<N-1>::value;
};
template <>
struct Factorial<0> {
    static constexpr int value = 1;
};
      


27.3 Compile-time Computation
Enables optimization and checks.

27.4 Using constexpr with TMP
Simplifies template metaprogramming.

27.5 Type Lists
Manipulate types at compile-time.

27.6 SFINAE and TMP
Enable/disable templates.

27.7 Expression SFINAE
Check expressions for validity.

27.8 Concepts and TMP
Improve TMP readability.

27.9 Practical Examples
Compile-time algorithms.

27.10 Tools and Libraries
Boost.MPL, Brigand.

28.1 Introduction to Threads
Concurrent execution in a program.

28.2 Creating Threads
Using `std::thread`.
#include <thread>
void func() { /* ... */ }
std::thread t(func);
t.join();
      


28.3 Thread Lifecycle
Start, run, join, detach.

28.4 Passing Arguments to Threads
Pass by value or reference.

28.5 Mutexes and Locks
Synchronize threads.

28.6 Deadlocks
Avoid threads waiting forever.

28.7 Condition Variables
Threads waiting for conditions.

28.8 Atomic Operations
Lock-free thread-safe operations.

28.9 Thread Safety Best Practices
Minimize shared state.

28.10 Practical Examples
Simple multithreaded programs.

29.1 What is Synchronization?
Coordinate thread access to resources.

29.2 Mutexes
Mutual exclusion locks.
std::mutex mtx;
mtx.lock();
// critical section
mtx.unlock();
      


29.3 std::lock_guard
RAII style mutex management.
std::lock_guard<std::mutex> lock(mtx);
// automatic unlock
      


29.4 std::unique_lock
More flexible locking.

29.5 Deadlocks and Avoidance
Lock order and timeout.

29.6 Condition Variables
Waiting and notifying.

29.7 Atomic Variables
Lock-free synchronization.

29.8 Barriers and Latches
Synchronize phases of execution.

29.9 Thread-safe Data Structures
Use concurrent containers.

29.10 Best Practices
Avoid unnecessary locking.

30.1 Introduction to Networking
Basics of network communication.

30.2 Sockets Overview
Endpoint for sending/receiving data.

30.3 Using Boost.Asio
Popular networking library.

30.4 TCP vs UDP
Reliable vs connectionless communication.

30.5 Creating a TCP Client
Connect and send data.

30.6 Creating a TCP Server
Listen and accept connections.

30.7 Asynchronous Networking
Non-blocking operations.

30.8 SSL/TLS Encryption
Secure communication.

30.9 Error Handling
Handling network errors.

30.10 Practical Networking Examples
Simple chat and file transfer.

31.1 Overview of STL Containers
Vector, list, deque, map, set, unordered_map.

31.2 Custom Comparators
Customize ordering in associative containers.
struct Compare {
    bool operator()(int a, int b) const {
        return a > b; // descending order
    }
};
std::set<int, Compare> s;
      


31.3 Allocators
Custom memory management for containers.

31.4 Container Adapters
Stack, queue, priority_queue usage.

31.5 Using Emplace Methods
Construct elements in place.
std::vector<std::string> v;
v.emplace_back("hello");
      


31.6 Iterators and Ranges
Using iterator categories and ranges.

31.7 Inserting and Erasing Elements
Efficient element management.

31.8 Move Semantics with Containers
Move instead of copy for performance.

31.9 Container Performance Considerations
Complexity of operations.

31.10 Best Practices
Choose container based on needs.

32.1 Structured Bindings
Unpack tuples or structs.
auto [x, y] = std::make_pair(1, 2);
cout << x << y;
      


32.2 if constexpr
Compile-time if statement.

32.3 std::optional
Optional values.
std::optional<int> opt = 5;
if (opt) cout << *opt;
      


32.4 std::variant
Type-safe unions.

32.5 std::any
Type-safe container for single values.

32.6 Filesystem Library
Manipulate paths and files.

32.7 Parallel Algorithms
Run algorithms in parallel.

32.8 String View
Non-owning views of strings.

32.9 Folding Expressions
Variadic template simplification.

32.10 std::byte
Type-safe byte manipulation.

33.1 Recap of Concepts
Constraints for template parameters.

33.2 Standard Concepts
std::integral, std::floating_point, etc.

33.3 Writing Custom Concepts

33.4 Introduction to Ranges
Range-based views and adaptors.

33.5 Using Views
Filter, transform ranges.

33.6 Range-based For Loops
Simplified iteration.

33.7 Combining Views
Compose operations.

33.8 Lazy Evaluation
Operations are evaluated on demand.

33.9 Performance Considerations
Efficient pipelines.

33.10 Practical Examples
Filtering and transforming containers.

34.1 What are Exceptions?
Mechanism to handle runtime errors.

34.2 Throwing Exceptions
throw std::runtime_error("Error occurred");
      


34.3 Catching Exceptions
try {
    // code that might throw
} catch (const std::exception& e) {
    cout << e.what();
}
      


34.4 Exception Specifications
`noexcept` keyword.

34.5 Stack Unwinding
Cleanup when exceptions thrown.

34.6 Custom Exception Types

34.7 Best Practices
Use exceptions only for exceptional cases.

34.8 RAII and Exceptions
Resource management.

34.9 Exception Safety Levels
Basic, strong, and no-throw guarantees.

34.10 Avoiding Exceptions
Alternatives like error codes.

35.1 Use Smart Pointers
Prefer `std::unique_ptr` and `std::shared_ptr`.

35.2 Prefer auto
Use `auto` to simplify code.

35.3 Use Range-based for Loops
Simplify iteration.

35.4 Use Const Correctness
Mark variables and methods `const`.

35.5 Avoid Raw Pointers
Manage resources safely.

35.6 Use noexcept
Mark non-throwing functions.

35.7 Prefer constexpr
Compute values at compile time.

35.8 Use Modern STL Algorithms
Utilize STL algorithms over manual loops.

35.9 Write Clear and Readable Code
Prioritize maintainability.

35.10 Continuous Learning
Stay updated with new standards and practices.

36.1 Introduction to Lambdas
Anonymous function objects for concise code.

36.2 Lambda Syntax
auto add = [](int a, int b) { return a + b; };
cout << add(2, 3);
      


36.3 Capturing Variables
Capture by value or reference.
int x = 10;
auto printX = [x]() { cout << x; };
      


36.4 Mutable Lambdas
Allow modification of captured values.
int x = 5;
auto increment = [x]() mutable { x++; cout << x; };
      


36.5 Generic Lambdas (C++14)
Template lambdas with auto parameters.
auto print = [](auto value) { cout << value; };
      


36.6 Lambdas and std::function
Store lambdas in `std::function` objects.

36.7 Using Lambdas with STL Algorithms
Inline predicates and transformations.
std::vector<int> v = {1, 2, 3};
std::for_each(v.begin(), v.end(), [](int n) { cout << n << " "; });
      


36.8 Closures and State
Lambdas can maintain state across calls.

36.9 Functional Programming Concepts
Immutability, higher-order functions.

36.10 Best Practices
Use lambdas for readability and flexibility.

37.1 Unique Pointer (std::unique_ptr)
Exclusive ownership and automatic deletion.
std::unique_ptr<int> ptr = std::make_unique<int>(10);
      


37.2 Shared Pointer (std::shared_ptr)
Shared ownership with reference counting.
std::shared_ptr<int> sp1 = std::make_shared<int>(20);
auto sp2 = sp1; // shared ownership
      


37.3 Weak Pointer (std::weak_ptr)
Non-owning reference to shared_ptr.

37.4 Custom Deleters
Use custom cleanup logic.

37.5 Avoiding Cycles
Use weak_ptr to prevent memory leaks.

37.6 Performance Considerations
Overheads and optimizations.

37.7 Moving vs Copying Smart Pointers

37.8 Thread Safety
shared_ptr is thread-safe for copies.

37.9 Common Pitfalls
Dangling pointers, double deletes.

37.10 Best Practices
Prefer smart pointers over raw pointers.

38.1 Combining Multiple Concepts
Using logical operators (`&&`, `||`).
template <typename T>
concept IntegralOrFloating = std::integral<T> || std::floating_point<T>;
      


38.2 Requires Clauses
Express template requirements.
template <typename T>
requires std::integral<T>
T add(T a, T b) {
    return a + b;
}
      


38.3 Concepts in Class Templates

38.4 Using Concepts for Better Error Messages

38.5 Default Template Arguments with Concepts

38.6 Concepts and SFINAE
More readable and robust.

38.7 Constraining Non-type Template Parameters

38.8 Using Concepts in Function Overloading

38.9 Practical Examples

38.10 Best Practices
Use concepts for clear and maintainable templates.

39.1 Coroutine Promise Types
Manage coroutine lifecycle.

39.2 Coroutine Handles
Control coroutine execution.

39.3 Awaitables and Awaiters
Define suspension points.

39.4 Writing Custom Coroutine Types

39.5 Coroutine Traits

39.6 Exception Handling in Coroutines

39.7 Coroutine Return Types

39.8 Using Coroutines with Async IO

39.9 Performance Considerations

39.10 Practical Examples

40.1 Range Concepts
`std::ranges::range`, `std::ranges::view`.

40.2 Range Adaptors
Using `views::filter`, `views::transform`.

40.3 Composing Range Operations

40.4 Lazy Evaluation

40.5 Views vs Containers

40.6 Using `ranges::to`

40.7 Custom Views

40.8 Range-based Algorithms

40.9 Performance Considerations

40.10 Practical Examples