01 — RAII
Tie resources to object lifetime: no finally, no leaks, deterministic.
struct File {
FILE* f = fopen("data", "r");
~File() { if (f) fclose(f); }
}; // cleanup runs at scope exit — always§ 02 — Eras · 1985
zero-cost abstraction — C with the brakes optional
Left: era context, features, and the 101 hello. Right: 3 core concepts, 4 deeper 201 lessons, the factorial specimen, and where C++ lives today — each column scrolls on its own.
Systems programmers wanted Simula’s abstraction without paying runtime for it. C++ promised zero-cost OOP on C’s metal.
The manual: a dozen ways to initialize, C’s undefined behavior inherited intact — plus compile times all its own.
Session one is the smallest program that still counts as speaking C++: what every tutorial prints first, in the dialect that mattered when the language arrived (1985).
#include <iostream>
int main() {
std::cout << "Hello, world\n";
}101First contact — hello world and 3 ideas that define how C++ reads. 201 — 4 lessons on mechanisms you meet after the factorial specimen: the sharp edges practitioners actually use.
3 fragments, each naming a habit of mind in C++. Read the note, then the code — together they are the 101 in one sitting.
01 — RAII
Tie resources to object lifetime: no finally, no leaks, deterministic.
struct File {
FILE* f = fopen("data", "r");
~File() { if (f) fclose(f); }
}; // cleanup runs at scope exit — always02 — templates
Generics by compile-time substitution — the STL is built from them.
template <typename T>
T min(T a, T b) { return a < b ? a : b; }03 — std::vector
The container that replaced manual memory for most application code.
std::vector<int> xs{3, 1, 2};
xs.push_back(7);
std::sort(xs.begin(), xs.end());The 201 assumes you have read the 101 and the specimen. Each lesson is one mechanism — what it is for, how it looks in code, and the trap or payoff that makes C++ distinctive at scale.
unique_ptr says “I own this”, shared_ptr says “we share this”, and weak_ptr breaks the cycle — three ways to state ownership the compiler then enforces.
std::unique_ptr<Ship> a = std::make_unique<Ship>();
std::shared_ptr<Log> b = std::make_shared<Log>();
std::weak_ptr<Log> guard = b; // does not keep it aliveAn rvalue can be stolen from instead of copied; combined with perfect forwarding, this removes whole classes of unnecessary allocations.
Ship::Ship(Ship&& other) noexcept
: name_(std::move(other.name_)) {}Concepts constrain templates at compile time with readable requirements, and if constexpr prunes branches before instantiation — the modern answer to SFINAE pain.
template <typename T>
requires std::integral<T>
T twice (T v) { return v + v; }Writing an iterator that satisfies the standard’s concepts makes your type usable with every STL algorithm — the point of the whole exercise.
struct ShipRange {
Ship* first, last;
Ship* begin() const { return first; }
Ship* end() const { return last; }
};The destructor: cleanup guaranteed at scope exit, resources tied to object lifetime — abstraction that costs zero at runtime. RAII is still C++’s best idea.
struct File {
FILE* f;
explicit File(const char* p) : f(fopen(p, "r")) {}
~File() { if (f) fclose(f); } // guaranteed
};runc++ fact.cpp -o fact && ./fact
Chrome, Unreal, Photoshop, trading systems — and the ML frameworks underneath Python’s AI boom.