C++ Complete Guide →
History of C++
The Birth of C++
C++ was created by Bjarne Stroustrup at Bell Labs in 1979, initially called "C with Classes". It was officially renamed C++ in 1983. The name itself is a programmer's joke — ++ is the increment operator in C, implying C++ is "one step above C".
Why Was C++ Created?
- Simulate complex systems — Stroustrup needed to simulate distributed computing for his PhD thesis
- C lacked abstraction — C was powerful but had no way to model real-world entities cleanly
- Simula had the right ideas — Object-oriented concepts from Simula were too slow for systems programming
- Goal: Combine the efficiency of C with the abstraction of Simula
Key Milestones
| Year | Version | Key Additions |
|---|---|---|
| 1979 | C with Classes | Classes, basic inheritance |
| 1983 | C++ | Virtual functions, function overloading |
| 1998 | C++98 | First ISO standard, STL, templates |
| 2003 | C++03 | Bug fixes for C++98 |
| 2011 | C++11 | Move semantics, lambdas, auto, nullptr |
| 2014 | C++14 | Generic lambdas, binary literals |
| 2017 | C++17 | std::optional, structured bindings, if constexpr |
| 2020 | C++20 | Concepts, ranges, coroutines, modules |
| 2023 | C++23 | std::expected, std::print, stacktrace |
Where C++ Is Used Today
- Operating Systems — Windows, parts of macOS/Linux kernels
- Game Engines — Unreal Engine, Unity runtime, Godot
- Databases — MySQL, MongoDB, Redis
- Browsers — Chrome (V8 engine), Firefox (SpiderMonkey)
- Embedded Systems — Firmware, automotive software, IoT
- Finance — High-frequency trading, risk systems
- Machine Learning — TensorFlow, PyTorch backends
Basics & Syntax
C++ Fundamentals
Hello World & Program Structure
Data Types
| Type | Size | Range | Example |
|---|---|---|---|
| int | 4 bytes | -2³¹ to 2³¹-1 | int x = 42; |
| long long | 8 bytes | -2⁶³ to 2⁶³-1 | long long x = 9e18; |
| float | 4 bytes | ~7 digits | float f = 3.14f; |
| double | 8 bytes | ~15 digits | double d = 3.14159; |
| char | 1 byte | -128 to 127 | char c = 'A'; |
| bool | 1 byte | true/false | bool b = true; |
| size_t | 8 bytes | 0 to 2⁶⁴-1 | size_t n = arr.size(); |
Variable Declaration & Initialization
Control Flow
Functions
Arrays & Strings
OOP Concepts
Object-Oriented Programming in C++
Classes & Objects
Inheritance
Inheritance Types
| Type | Public members become | Protected members become |
|---|---|---|
| public | public | protected |
| protected | protected | protected |
| private | private | private |
Abstract Classes & Pure Virtual
Operator Overloading
The Rule of Three / Five / Zero
Memory Management
Manual Memory Management in C++
Stack vs Heap
| Feature | Stack | Heap |
|---|---|---|
| Allocation | Automatic (LIFO) | Manual (new/delete) |
| Speed | Very fast | Slower (allocation overhead) |
| Size | Small (~1-8 MB) | Large (GBs) |
| Lifetime | Scope-bound | Until explicitly freed |
| Error | Stack overflow | Memory leak / dangling ptr |
new and delete
RAII — Resource Acquisition Is Initialization
Memory Layout of a C++ Object
Common Memory Bugs: Memory leak (forgetting delete), dangling pointer (delete then use), double free (delete twice), buffer overflow (writing past array bounds). Smart pointers eliminate most of these.
Pointers & References
Pointers & References
Pointers Basics
Pointer to Pointer, const Pointers
References
Move Semantics (C++11)
Function Pointers & std::function
Smart Pointers
Smart Pointers (C++11)
Smart pointers are RAII wrappers around raw pointers. They automatically manage memory — no manual delete needed. Defined in <memory>.
unique_ptr — Exclusive Ownership
Rule: Prefer unique_ptr by default. It has zero overhead compared to a raw pointer and makes ownership explicit.
shared_ptr — Shared Ownership
weak_ptr — Non-Owning Observer
Circular Reference Problem
Comparison Table
| Feature | unique_ptr | shared_ptr | weak_ptr |
|---|---|---|---|
| Ownership | Exclusive | Shared | None |
| Copy | ❌ (move only) | ✅ | ✅ |
| Ref count | No overhead | Atomic count | Doesn't increment |
| Use for | Default choice | Shared resources | Caches, observer pattern |
| Thread safe? | No (by design) | Ref count yes, data no | Same as shared_ptr |
Interview Tip: Always prefer make_unique and make_shared over new. They're exception-safe and, for shared_ptr, allocate the control block and object together (better cache performance).
STL — Standard Template Library
Standard Template Library
Sequence Containers
Associative Containers
Container Adaptors
STL Algorithms
Iterators
Templates
Templates — Generic Programming
Function Templates
Class Templates
Template Specialization
Variadic Templates (C++11)
Exception Handling
Exception Handling in C++
Try-Catch-Throw
Standard Exception Hierarchy
Custom Exceptions
noexcept Specifier
Best Practice: Always catch exceptions by const reference (catch (const std::exception& e)). Never catch by value — it causes object slicing.
C++11 / C++14 Modern Features
C++11 — The Modern Revolution
Lambda Expressions
auto & decltype
Initializer Lists & Uniform Initialization
enum class (Scoped Enums)
nullptr, override, final, delete, default
range-based for, tuple, tie
C++17 Features — In Detail
C++17 — Key Features Explained
1. Structured Bindings
Unpack any struct, array, or tuple directly into named variables — no more get<0>().
2. std::optional
Represents a value that may or may not be present — a type-safe alternative to returning -1, 0, or nullptr as sentinel values.
3. std::variant
A type-safe union — holds exactly one value from a list of types. Safer than C-style unions.
4. std::any
Holds a value of any type — like a void* but type-safe.
5. if constexpr
Compile-time if statement. Eliminates template specializations in many cases. Unused branch is not compiled — removes the need for tag dispatch or SFINAE.
6. if/switch with Initializer
7. Fold Expressions
8. std::string_view
A non-owning reference to a string — avoids copying. Use for read-only string parameters instead of const string&.
9. std::filesystem
10. Parallel Algorithms
11. Class Template Argument Deduction (CTAD)
12. Inline Variables
| Feature | Purpose | When to Use |
|---|---|---|
| Structured Bindings | Unpack aggregates | Loop over maps, unpack pairs/structs |
| std::optional | Optional value | Functions that may fail/find nothing |
| std::variant | Type-safe union | Holding one of several types |
| if constexpr | Compile-time branching | Template meta-programming |
| string_view | Non-owning string ref | Read-only string parameters |
| std::filesystem | File system ops | File/directory manipulation |
| Parallel Algorithms | Multi-core STL | Large data processing |
Concurrency & Multithreading
C++11 Concurrency Library
std::thread
Mutex & Lock
Condition Variable
std::future & std::async
Atomic Operations
Thread Pool Pattern
Interview Tip: Know the difference between mutex (exclusive), shared_mutex (readers-writer), atomic (lock-free), and when to use each. atomic is fastest but limited to simple types; mutex is general purpose.