BOOK / SOURCE & READING RECORD
The C++ Programming Language
Bjarne Stroustrup
4th edition, second printing June 2013, ISBN 9780321563842;另读 first printing May 2013 出版社样章
The C++ Programming Language
The complete body text of chapters 1–44 (print pages 3–1279) has been read in sections, including code, tables, and end-of-chapter advice, plus the prefaces of the various printings; private text L140–59048 covers this continuously. Subsequently, 126 already-located original PDF figures, formulas, and surrounding pages were checked directly, filling in visual content such as object layouts, inheritance arrows, matrices, streams, and concurrency. “full” means the body text and the identified substantial figures have been read; it does not mean every one of the 1,366 PDF pages was collated page by page. The index was only sampled for navigation, not read entry by entry. The original book is a C++11 baseline; C++20 differences are listed separately.
Edition, actual reading range, and original sources →Sources
- Author’s fourth-edition page
Bibliographic information, table of contents, exercises, and sample-chapter entry points; not the full book
- Publisher’s official sample chapters
Chapters 2–5, print pages 37–132
- Author’s errata
Corrections related to chapters 3–5; the full errata pages were not treated as already-read chapters
Publicly readable fourth-edition full text (private research source; no unauthorized-republication claim)
Second printing, June 2013; body text of chapters 1–44 fully read; additionally checked 126 precisely located PDF figure/formula pages; private ledger records physical page numbers
The research copy is not linked from this site.
Invariants and commit-on-success are the same design thread
§2.4.3; §13.3, §13.6; §17.5–17.6; §29.2–29.4, pp. 55–57, 354–387, 507–523, 828–849
From the tour’s Vector through raw storage management in the exceptions chapter, to copy, move, and Matrix, the thread that runs through the whole book is that an object represents a maintainable promise. Construction establishes the promise; member operations maintain it; resource members let construction fail yet still compose cleanup. Copying is not byte-for-byte identity, and moving is not emptying every source object; self-pointers, shared state, and views turn relationships among members into a real design responsibility. Preparing a replacement state before committing can preserve the old value; reusing capacity saves allocations but may change the failure guarantee. Business types should prefer composing standard resource handles; hand-write special members only when an invariant requires it, and do not treat teaching containers as production implementations.
Generic programming is deleting unnecessary assumptions
§12.3; §14.2.4; §23.4.6.3; §24.2–24.4; §26.2–26.3; §28.4, pp. 326–330, 396–397, 680–682, 700–719, 743–758, 795–804
The book extracts iterators and operations from a concrete summation, then discusses concepts, traits, policies, and instantiation. True reuse is not wrapping everything in templates; it is distinguishing what the problem requires from capabilities the current implementation happens to use: the accumulator type need not equal the element type, algorithms need not require all containers to share a common base, and a member’s ordering requirements need not be imposed on the whole class. Template interfaces are also affected by the name-lookup environment; ADL is not a fallback path that starts only after ordinary lookup fails. C++20 concepts can write some interface requirements into the syntax, but they cannot automatically prove comparison relations, value semantics, or complexity. The book’s Enable_if and concept discussion belongs to the C++11 era and should not be labeled as a modern requires example.
Owning data, observing data, and organizing layout must be kept separate
§29.2–29.4; §31.2–31.4; §32.5; §34.2; §36.3; §37.2, pp. 828–849, 888–920, 939–944, 974–987, 1037–1048, 1058–1063
Matrix and Matrix_ref separate storage ownership from slice mapping; string and regex captures likewise separate owning characters from borrowed iterators. These examples remind us that returning a seemingly ordinary value does not prove it owns the data it refers to, and auto does not erase borrow lifetime. Container choice is likewise not just comparing big-O: node location, locality, allocation, and iterator invalidation all affect the interface. reserve only prepares space; resize actually creates elements. remove only compresses a logical range; erase actually changes the container’s size. Modern span and string_view continue this division of labor, but mdspan is C++23, not a facility already in C++20; any view must separately prove that the source storage lives long enough.
Concurrency: define result semantics first, then choose the execution mechanism
§5.3; §41.2–41.5; §42.2–42.4, pp. 113–123, 1193–1207, 1210–1250
Atomicity, ownership, and synchronization are three different things: smart pointers manage lifetime, atomic supplies constraints on individual operations, and a complete protocol must still specify conflicting access and happens-before. A thread handle may still be joinable even after the corresponding work has finished; detach only gives up observation, it does not remove borrow responsibility. A condition variable waits for a lock-protected predicate, not for a single notification; future organizes value, exception, and completion state in the same result channel. The lowest-position match, earliest-completed match, and all-matches of a parallel find are not the same function; choose the semantics before talking about speedup. C++20’s jthread, stop requests, and atomic waits are later tools and should not be back-written as content already covered in this book.
Related fundamentals
Construction and destruction orderRAII: Give Cleanup Responsibility to ObjectsDeep copy, shallow copy, and the Rule of Zero / Five