
C++
First appeared 1985 (as 'C with Classes' from 1979) · Bjarne Stroustrup
Zero-overhead abstraction — you pay only for what you use, and what you use is fast.
Overview
C++ is a high-level, general-purpose programming language created as an extension of the C language by Bjarne Stroustrup in the early 1980s. It incorporates object-oriented, procedural, and generic programming features, making it extremely versatile and powerful. C++ has been widely used for developing operating systems, game engines, real-time simulations, high-performance applications, and large-scale enterprise software. Its combination of low-level memory control and high-level abstractions allows developers to write both efficient system-level code and complex application logic. The language provides features such as classes, inheritance, polymorphism, templates, exception handling, and the Standard Template Library (STL), which includes containers, algorithms, and iterators. Over the decades, C++ has influenced many modern languages including C#, Java, and Rust, and remains a cornerstone of software development in areas requiring performance and reliability. The language continues to evolve through ISO standardization, ensuring modern features while maintaining backward compatibility. C++’s rich ecosystem includes compilers, IDEs, libraries, and tools that support development across multiple platforms, from embedded systems to large-scale enterprise applications.
Key facts
The reference details, without the paragraph.
- First appeared
- 1985 (as 'C with Classes' from 1979)
- Designed by
- Bjarne Stroustrup at Bell Labs
- Typing
- Static and strong, with templates providing compile-time generic programming
- Execution
- Compiled ahead of time to native machine code
- Memory model
- Manual, but managed through RAII and smart pointers rather than raw `new`/`delete`
- Package manager
- vcpkg or Conan; no official standard
- File extensions
- .cpp, .cc, .hpp, .h, .ixx
- Current standard
- C++23, with C++26 in progress and C++17/20 most common in production
- Guiding principle
- Zero-overhead abstraction — unused features cost nothing at runtime
- Licence
- Open ISO standard; GCC, Clang and MSVC implement it independently
History
How the language got here — the decisions that still shape how you write it.
C++ was created by Bjarne Stroustrup at Bell Labs in the early 1980s as an enhancement to the C programming language, aiming to combine the efficiency of C with higher-level abstractions to support large-scale software development. Initially called 'C with Classes', it introduced features such as classes, inheritance, and strong type checking while maintaining compatibility with existing C code. Over the years, C++ evolved into a mature language with multiple paradigms, including procedural, object-oriented, and generic programming, enabling developers to tackle a wide variety of problems. The Standard Template Library (STL), added in the 1990s, brought standardized containers, algorithms, and iterators, simplifying common programming tasks and promoting code reuse. C++ has been fundamental in building critical systems, including operating systems, real-time simulations, graphical engines, compilers, and databases. Its performance and flexibility have made it the language of choice for applications where efficiency is paramount, such as video games, financial software, and embedded systems. The language has been continuously updated through ISO standards (C++98, C++03, C++11, C++14, C++17, C++20, and upcoming C++23), adding features like auto typing, smart pointers, concurrency support, lambda expressions, modules, and enhanced template programming. Bjarne Stroustrup’s vision emphasized both power and maintainability, making C++ suitable for both system-level programming and complex application development. The C++ community is large and active, organizing conferences, maintaining open-source libraries, and contributing to the language’s evolution. C++’s influence on modern computing is profound; many programming languages, frameworks, and software engineering practices have drawn inspiration from its design principles. Its combination of performance, flexibility, and expressive power ensures that C++ remains a critical language for software developers worldwide, continuing to shape the future of computing.
- 1979
C with Classes
Bjarne Stroustrup, wanting Simula's abstractions with C's efficiency for his distributed systems research, starts adding classes to C at Bell Labs.
- 1985
C++ released
Renamed with the increment operator, and given virtual functions, operator overloading and references. *The C++ Programming Language* is published the same year.
- 1998
C++98 and the STL
The first ISO standard incorporates Alexander Stepanov's Standard Template Library. Containers, iterators and algorithms as separate, composable pieces is a genuinely novel design and still the library's foundation.
- 2011
C++11 — 'a new language'
Move semantics, `auto`, lambdas, range-based `for`, smart pointers, `nullptr` and a threading model arrive together. Stroustrup describes it as feeling like a new language, and modern C++ dates from here.
- 2014–2017
Steady refinement
C++14 smooths C++11's rough edges; C++17 adds structured bindings, `std::optional`, `std::variant`, `string_view`, filesystem support and parallel algorithms.
- 2020
C++20 — the big four
Concepts finally make template errors readable, ranges make algorithms composable, coroutines give first-class async, and modules begin to address the header model's compile-time cost.
- 2023
C++23
`std::expected` for error handling without exceptions, `std::print`, multidimensional subscripting, and a considerably more usable ranges library.
- Today
Where performance is non-negotiable
Game engines, browsers, databases, trading systems, CAD, and the machine-learning frameworks whose Python interfaces get the credit — all C++ underneath.
What it is good at
The reasons teams pick it, stated concretely.
Abstraction without a runtime tax
Templates and inlining mean a `std::sort` over a custom comparator compiles to code as tight as a hand-written loop. You can build expressive interfaces and still generate the machine code you would have written by hand.
RAII solves resource management
Tie a resource's lifetime to an object's scope and it is released automatically, including when an exception unwinds. Files, locks, sockets and memory all follow one rule. It is arguably C++'s most important contribution to language design.
Complete control when you need it
Memory layout, allocation strategy, alignment, cache behaviour and whether a call is virtual are all yours to decide. In a domain where a microsecond matters, no managed language can offer this.
A remarkable standard library
Containers, algorithms, ranges, threading, chrono, regex and filesystem — all templated, all generic, all fast. `std::sort` is typically an introsort that outperforms most hand-rolled attempts.
Compile-time computation
`constexpr` and `consteval` let real work happen during compilation — lookup tables, parsing, validation — so the binary does nothing at startup that could have been settled by the compiler.
Trade-offs
Every language costs you something. Knowing what, before you commit, is the whole point.
The language is enormous
The standard runs past 2,000 pages. There are several dialects in active use — C++98-with-classes, modern C++11-and-later, and template-heavy library code — and reading all three well takes years.
The same memory hazards as C, unless you are disciplined
Dangling references, iterator invalidation and use-after-free are all reachable. Modern practice — smart pointers, containers, no raw `new` — avoids most of them, but nothing enforces it.
Template error messages
A single mistake can produce hundreds of lines of instantiation trace. C++20 concepts improve this substantially, but a lot of existing library code predates them.
Slow compilation
Header inclusion means the same code is parsed repeatedly across translation units. Large projects measure builds in tens of minutes. Precompiled headers, forward declarations, unity builds and modules all help, none fully solve it.
No standard package management
vcpkg and Conan work well, but they are conventions rather than a language feature, and CMake remains the price of entry for cross-platform builds.
Code examples
Not syntax tours — the idioms that make code read like the language rather than a translation of another one.
#include <fstream>
#include <mutex>
#include <memory>
class Logger {
std::ofstream file_;
std::mutex mutex_;
public:
explicit Logger(const std::string& path) : file_(path, std::ios::app) {
if (!file_) throw std::runtime_error("cannot open log");
}
void write(std::string_view line) {
std::lock_guard<std::mutex> guard(mutex_); // unlocks on scope exit
file_ << line << '\n';
}
// No destructor needed: ofstream closes itself, mutex cleans itself up.
};
auto logger = std::make_unique<Logger>("app.log");
logger->write("started"); // freed automatically when the pointer goes out of scope#include <memory>
#include <vector>
struct Node {
int value;
std::vector<std::unique_ptr<Node>> children; // exclusive ownership
Node* parent = nullptr; // non-owning back-reference
};
auto root = std::make_unique<Node>(Node{1, {}, nullptr});
auto child = std::make_unique<Node>(Node{2, {}, root.get()});
root->children.push_back(std::move(child));
// child is now empty; root owns the whole tree and frees it in one go.#include <ranges>
#include <vector>
#include <print>
std::vector<int> readings{12, -3, 45, 7, -18, 33, 21};
auto top = readings
| std::views::filter([](int n) { return n > 0; })
| std::views::transform([](int n) { return n * 2; })
| std::views::take(3);
for (int value : top) std::print("{} ", value); // 24 90 14#include <concepts>
#include <ranges>
template <std::ranges::input_range R>
requires std::totally_ordered<std::ranges::range_value_t<R>>
auto largest(const R& range) {
auto it = std::ranges::max_element(range);
return it == std::ranges::end(range)
? std::nullopt
: std::optional{*it};
}
auto biggest = largest(std::vector{3, 9, 4}); // std::optional<int>{9}
// largest(42); // error names the failed constraint, not 200 lines of template traceCommon pitfalls
The mistakes that cost everyone an afternoon at least once.
Raw `new` and `delete`
Every manual `delete` is a leak waiting for an early return or an exception. Use `make_unique`, `make_shared` and containers; in modern C++ you should rarely write either keyword.
Iterator and reference invalidation
`push_back` may reallocate a vector, invalidating every existing iterator, pointer and reference into it. Erasing inside a loop invalidates too — use the iterator returned by `erase`.
Object slicing
Assigning a derived object to a base-class variable copies only the base part and silently discards the rest. Store polymorphic objects by reference or smart pointer, never by value.
Dangling `string_view` and references
`string_view` does not own its characters. Binding one to a temporary — or returning one that refers to a local — leaves you reading freed memory.
Copying where a move would do
Passing large containers by value in a hot path copies them. Take by `const&` to observe, by value plus `std::move` to take ownership.
Forgetting a virtual destructor
Deleting a derived object through a base pointer without a virtual destructor is undefined behaviour and skips the derived destructor. Any class meant for inheritance needs one.
In production
Where it is running at scale, and what it is doing there.
Adobe
Desktop applications like Photoshop and Illustrator.
Microsoft
Windows OS components, Office suite, and high-performance apps.
Google
High-performance backend systems and Chrome browser.
Epic Games
Game engine development (Unreal Engine) and game development.
Learning path
A realistic order to learn things in, with something to build at each step.
- 1
Weeks 1–3
Core language, modern style from the start
Types, functions, references, `auto`, range-based `for`, `std::string` and `std::vector`. Learn the modern idioms first — do not start with `new`, `delete` and raw arrays and unlearn them later.
Build this: Write a program that reads words from a file and reports frequencies using `std::map`.
- 2
Weeks 4–6
Classes, RAII and the object model
Constructors and destructors, the rule of zero, copy versus move, `const` correctness, and why RAII matters. Understand what happens when an exception propagates through your objects.
Build this: Implement a resource wrapper — a file handle or buffer — that is correct under copy, move and exception.
- 3
Weeks 7–10
The standard library
Containers and their complexity guarantees, iterators, algorithms, `std::optional`, `std::variant`, `string_view`, smart pointers, and `chrono`. Knowing what is already in the library prevents most reinvention.
Build this: Rewrite earlier code using standard algorithms instead of hand-written loops and measure the difference.
- 4
Months 4–6
Templates, concurrency and builds
Function and class templates, `constexpr`, concepts, threads, `std::atomic` and the memory model, plus CMake and a package manager. This is where C++ becomes genuinely powerful.
Build this: Build a thread-safe queue and a small CMake project that consumes an external dependency.
- 5
Ongoing
Performance and correctness in earnest
Cache behaviour and data-oriented design, move semantics in depth, profiling with perf or VTune, sanitisers, and the C++ Core Guidelines. Read the standard library implementation when a question gets specific.
Build this: Profile a hot loop and improve it by changing the data layout rather than the algorithm.
Ecosystem and tooling
The tools you will end up installing whichever project you join.
| Tool | Category | What it does |
|---|---|---|
| CMake | Build | The de facto cross-platform build system; almost every library expects it |
| vcpkg / Conan | Packaging | Dependency managers that make third-party libraries a one-line addition |
| GCC / Clang / MSVC | Compiler | The three major compilers; testing against more than one catches non-portable assumptions |
| Catch2 / GoogleTest | Testing | The standard unit-testing frameworks — Catch2 is header-only, GoogleTest has richer mocking |
| AddressSanitizer / ThreadSanitizer | Debugging | Runtime detection of memory errors and data races |
| clang-tidy / clang-format | Code quality | Static analysis against the Core Guidelines, and automatic formatting |
| Compiler Explorer | Tooling | See the assembly your code generates across compilers and flags — invaluable for understanding cost |
| perf / VTune | Performance | Sampling profilers for finding where the time actually goes |
C++ libraries
43 catalogued, each with installation, worked examples and best practices.
Boost
A vast collection of peer-reviewed C++ libraries, many of which became the standard library.
Developer UtilitiesQt
The most complete cross-platform C++ application framework — GUI and much else.
Developer UtilitiesPOCO C++ Libraries
POCO (Portable Components) is a set of modern C++ libraries that provide building blocks for network-centric, portable applications. It includes modules for networking, HTTP, XML, JSON, threading, file system access, and more.
Web & HTTPnlohmann-json
JSON that behaves like a native C++ type — intuitive, header-only, widely adopted.
Web & HTTPfmt
Fast, safe, Python-style string formatting — the basis of C++20's `std::format`.
Developer Utilitiesspdlog
Very fast C++ logging, header-only, with synchronous and asynchronous modes.
Developer Utilities
Frequently asked
Is C++ still worth learning?
Yes, in the domains where it is the answer: game engines, browsers, databases, embedded systems, high-frequency trading, robotics, and the compute kernels behind machine-learning frameworks. It is not the right first language for web or scripting work, and it is not going anywhere in the fields that need it.
What is 'modern C++' and why does it matter?
C++11 and later, written with smart pointers, containers, `auto`, range-based loops, move semantics and RAII rather than raw pointers and manual memory. It is a genuinely different experience from the C++ of the 1990s — and much of the material online still teaches the old style.
C++ or Rust for a new systems project?
Rust if memory safety is the priority and the team can absorb the borrow checker's learning curve. C++ if you need a mature ecosystem in your domain — graphics, audio, CAD, scientific computing — or must integrate with a large existing codebase. Both compile to comparable machine code.
Which standard should I target?
C++20 for a new project on current toolchains: concepts and ranges alone justify it. C++17 is the widely safe baseline. Avoid starting anything new at C++11 or earlier unless a platform constraint forces it.
How do I keep compile times reasonable?
Include less in headers — forward declare where you can — use precompiled headers, split large translation units, cache with ccache, and prefer explicit instantiation for heavy templates. Modules address the root cause and are increasingly usable.
Should I use exceptions?
For most applications, yes — they keep error handling out of the happy path and are effectively free when nothing throws. Game engines and embedded projects often disable them for deterministic timing and binary size, in which case `std::expected` in C++23 gives a good alternative.




