Skip to content
C++
🔀

C++ for Python & Java Developers

The mental model shift is real but smaller than it looks. You already know algorithms, data structures, and OOP. What changes: memory lives on the stack, copies are explicit, and destructors replace garbage collection.

Estimated ramp-up

Python developer: ~30–40 hours to productive C++. Java developer: ~20–30 hours (the type system and compilation model will feel familiar). The hardest part is internalizing value semantics and ownership — not the syntax.

Key mental model shifts

ConceptPython / JavaC++Why
Memory managementGC handles deallocationRAII: destructor frees resources when scope endsDeterministic, zero-overhead, works in all environments
VariablesReferences to heap objectsValues on the stack by defaultNo hidden allocation; copies are explicit
Listslist = [1, 2, 3]std::vector<int> v = {1, 2, 3};Contiguous memory, typed, zero-overhead iteration
Dictsd = {'a': 1}std::unordered_map<std::string, int> d;Typed keys + values; O(1) amortized lookup
Null referencesString s = null;std::optional<std::string> or raw nullptr only for pointersNull pointer bugs are the most common C++ crash — use optional
CompilationInterpreted / JIT at runtimeCompiled to native machine code ahead of time10–100× faster at runtime; errors caught at compile time
GenericsRuntime duck typing / type erasureTemplates: compile-time specialization, zero overheadType errors at compile time; inlined code, no boxing
Interfacesinterface Printable { void print(); }Concepts (C++20) or abstract class with virtual functionsConcepts check at compile time; virtual dispatch costs one pointer indirection
Stringsstr (Python) / String (Java) — immutablestd::string (mutable, owned) or std::string_view (non-owning view)string_view avoids copies when you just need to read
Error handlingraise Exception / try: except:Exceptions (throw/catch) or std::expected<T, E> (C++23)expected = error as value, no exception overhead, monadic chaining

The things that will bite you first

Undefined behavior is silent

C++ has no runtime bounds checker by default. Out-of-bounds access, use-after-free, signed overflow — the program may silently produce wrong results or crash unpredictably. Use AddressSanitizer + UBSan in development.

Copying is expensive — move when you can

Passing a std::vector to a function copies it (unlike Python/Java references). Use const& to read without copying. Use std::move() when handing off ownership.

Header order matters

Unlike Java's import or Python's import, C++ #include literally pastes the file. Include order can cause subtle issues; use #pragma once or include guards.

No garbage collector means you handle lifetimes

If a raw pointer outlives the object it points to, you have a dangling pointer. Prefer smart pointers and let RAII manage lifetimes.

Topics in order

Why C++ is compiled and what that means for you

Header files, translation units, the linker — why they exist and how to think about them coming from a dynamic language.

Value semantics: copies are explicit

In Python/Java, assigning variables copies references. In C++, it copies values. When to use references (&), pointers (*), and when to move.

Manual memory — but you rarely write it

unique_ptr and shared_ptr are C++'s 'smart GC' — RAII means objects clean up themselves. You almost never call new/delete directly.

RAII: destructors are your finally block

The destructor runs when a variable goes out of scope — even on exceptions. This is how C++ handles file handles, mutexes, and network connections.

std::vector, std::map, std::unordered_map

The C++ equivalents of list and dict. Same semantics, explicit types, faster than Python equivalents by 10-50×.

Templates: generics without boxing

C++ templates are monomorphized at compile time — a sorted list of ints generates different code than a list of strings, but both are as fast as hand-written.

std::optional — replace nullable references

Java's Optional<T> and Python's None are equivalent to C++23 std::optional<T>. Monadic methods: and_then, transform, or_else.

std::string vs std::string_view

string owns its data (like Java's String). string_view is a non-owning view — pass it to functions that just read, never store it past the string's lifetime.

Lambdas and closures

C++ lambdas are similar to Python closures and Java's functional interfaces. Capture by value or reference — with explicit choice about what you capture.

Concurrency: threads without a GIL

C++ threads run truly in parallel — no GIL. std::mutex, std::atomic, and std::jthread (C++20). Comes with data race responsibility.

Build systems and dependency management

CMake + vcpkg/conan replaces pip and Maven. Compilation units, libraries, and linking — the mental model you need.

Exceptions vs std::expected

C++ exceptions look like Java/Python but have different performance characteristics. std::expected<T, E> (C++23) is the modern alternative.