Beautiful C++: 30 Core Guidelines for Writing Clean, Safe, and Fast Code

Book description

Discover the Beauty of Modern C++

Beautiful C++ presents the C++ Core Guidelines from a developer’s point of view with an emphasis on what benefits can be obtained from following the rules and what nightmares can result from ignoring them. For true geeks, it is an easy and entertaining read. For most software developers, it offers something new and useful.”

—Bjarne Stroustrup, inventor of C++ and co-editor of the C++ Core Guidelines

Writing great C++ code needn’t be difficult. The C++ Core Guidelines can help every C++ developer design and write C++ programs that are exceptionally reliable, efficient, and well-performing. But the Guidelines are so jam-packed with excellent advice that it’s hard to know where to start. Start here, with Beautiful C++.

Expert C++ programmers Guy Davidson and Kate Gregory identify 30 Core Guidelines you’ll find especially valuable and offer detailed practical knowledge for improving your C++ style. For easy reference, this book is structured to align closely with the official C++ Core Guidelines website.

Throughout, Davidson and Gregory offer useful conceptual insights and expert sample code, illuminate proven ways to use both new and longstanding language features more successfully, and show how to write programs that are more robust and performant by default.

  • Avoid “bikeshedding”: stop wasting valuable time on trivia
  • Don’t hurt yourself by writing code that will cause problems later
  • Know which legacy features to avoid and the modern features to use instead
  • Use newer features properly, to get their benefits without creating new problems
  • Default to higher-quality code that’s statically type-safe, leak resistant, and easier to evolve
  • Use the Core Guidelines with any modern C++ version: C++20, C++17, C++14, or C++11

There’s something here to improve virtually every program you write, design, or maintain.

For ease of experimentation, all sample code is available on Compiler Explorer at

Register your book for convenient access to downloads, updates, and/or corrections as they become available. See inside book for details.

Table of contents

  1. Cover Page
  2. About This eBook
  3. Halftitle Page
  4. Title Page
  5. Copyright Page
  6. Pearson’s Commitment to Diversity, Equity, and Inclusion
  7. Contents
  8. Selected C++ Core Guidelines
  9. Foreword
  10. Preface
    1. About This Book
    2. Access the Code
  11. Acknowledgments
  12. About the Authors
  13. Section 1: Bikeshedding is bad
    1. Chapter 1.1. P.2: Write in ISO Standard C++
      1. What is ISO Standard C++?
      2. Encapsulating variations
      3. Learning the old ways
      4. Staying on top of developments to the standard
    2. Chapter 1.2. F.51: Where there is a choice, prefer default arguments over overloading
      1. Introduction
      2. Refining your abstraction: Additional arguments or overloading?
      3. The subtleties of overload resolution
      4. Back to the example
      5. The unambiguous nature of default arguments
      6. Alternatives to overloading
      7. Sometimes you must overload
      8. Summary
    3. Chapter 1.3. C.45: Don’t define a default constructor that only initializes data members; use in-class member initializers instead
      1. Why have default constructors anyway?
      2. How do you initialize a data member?
      3. What happens when two people maintain a class?
      4. Summary
    4. Chapter 1.4. C.131: Avoid trivial getters and setters
      1. An archaic idiom
      2. Abstraction
      3. Mere Encapsulation
      4. Class Invariants
      5. Nouns and Verbs
      6. Summary
    5. Chapter 1.5. ES.10: Declare one name (only) per declaration
      1. Let me introduce you
      2. Backward compatibility
      3. Writing clearer declarations
      4. Structured binding
      5. Summary
    6. Chapter 1.6. NR.2: Don’t insist to have only a single return-statement in a function
      1. Rules evolve
      2. Ensuring cleanup
      3. Using RAII
      4. Writing good functions
      5. Summary
  14. Section 2: Don’t hurt yourself
    1. Chapter 2.1. P.11: Encapsulate messy constructs, rather than spreading through the code
      1. All in one gulp
      2. What it means to encapsulate a messy construct
      3. The purpose of language and the nature of abstraction
      4. Levels of abstraction
      5. Abstraction by refactoring and drawing the line
      6. Summary
    2. Chapter 2.2. I.23: Keep the number of function arguments low
      1. How much should they earn?
      2. Simplifying matters through abstraction
      3. Do as little as possible, but no less
      4. Real-life examples
      5. Summary
    3. Chapter 2.3. I.26: If you want a cross-compiler ABI, use a C-style subset
      1. Creating libraries
      2. What is an ABI?
      3. Paring back to the absolute minimum
      4. Exception propagation
      5. Summary
    4. Chapter 2.4. C.47: Define and initialize member variables in the order of member declaration
      1. Summary
    5. Chapter 2.5. CP.3: Minimize explicit sharing of writable data
      1. Traditional execution model
      2. Wait, there’s more
      3. Avoiding deadlocks and data races
      4. Setting aside locks and mutexes
      5. Summary
    6. Chapter 2.6. T.120: Use template metaprogramming only when you really need to
      1. std::enable_if => requires
      2. Summary
  15. Section 3: Stop using that
    1. Chapter 3.1. I.11: Never transfer ownership by a raw pointer (T*) or reference (T&)
      1. Using the free store
      2. The performance cost of smart pointers
      3. Using unadorned reference semantics
      4. gsl::owner
      5. Summary
    2. Chapter 3.2. I.3: Avoid singletons
      1. Global objects are bad
      2. Singleton Design Pattern
      3. Static initialization order fiasco
      4. How to hide a singleton
      5. But only one of these should ever exist
      6. Wait a moment…
      7. Summary
    3. Chapter 3.3. C.90: Rely on constructors and assignment operators, not memset and memcpy
      1. Chasing maximum performance
      2. The horrendous overhead of the constructor
      3. The simplest possible class
      4. What is the standard talking about anyway?
      5. But what about memcpy?
      6. Never underestimate the compiler
      7. Summary
    4. Chapter 3.4. ES.50: Don’t cast away const
      1. Story time
      2. Dealing with rather more data
      3. The const firewall
      4. Implementing a dual interface
      5. Caching and lazy evaluation
      6. Two types of const
      7. Surprises with const
      8. Summary
    5. Chapter 3.5. E.28: Avoid error handling based on global state (e.g. errno)
      1. Error handling is hard
      2. C and errno
      3. Return codes
      4. Exceptions
      5. <system_error>
      6. Boost.Outcome
      7. Why is error handling so hard?
      8. Light at the end of the tunnel
      9. Summary
    6. Chapter 3.6. SF.7: Don’t write using namespace at global scope in a header file
      1. Don’t do this
      2. Disambiguation
      3. Using using
      4. Where do the symbols go?
      5. An altogether more insidious problem
      6. Solving the problem of cluttered scope resolution operators
      7. The temptation and The Fall
      8. Summary
  16. Section 4: Use this new thing properly
    1. Chapter 4.1. F.21: To return multiple “out” values, prefer returning a struct or tuple
      1. The shape of a function signature
      2. Documenting and annotating
      3. Now you can return an object
      4. You can also return a tuple
      5. Passing and returning by non-const reference
      6. Summary
    2. Chapter 4.2. Enum.3: Prefer class enums over “plain” enums
      1. Constants
      2. Scoped enumerations
      3. Underlying type
      4. Implicit conversion
      5. Summary
      6. Postscript
    3. Chapter 4.3. ES.5: Keep scopes small
      1. The nature of scope
      2. Block scope
      3. Namespace scope
      4. Class scope
      5. Function parameter scope
      6. Enumeration scope
      7. Template parameter scope
      8. Scope as context
      9. Summary
    4. Chapter 4.4. Con.5: Use constexpr for values that can be computed at compile time
      1. From const to constexpr
      2. Default C++
      3. Using constexpr
      4. inline
      5. consteval
      6. constinit
      7. Summary
    5. Chapter 4.5. T.1: Use templates to raise the level of abstraction of code
      1. Story time
      2. Raising the level of abstraction
      3. Function templates and abstraction
      4. Class templates and abstraction
      5. Naming is hard
      6. Summary
    6. Chapter 4.6. T.10: Specify concepts for all template arguments
      1. How did we get here?
      2. Constraining your parameters
      3. How to abstract your concepts
      4. Factoring via concepts
      5. Summary
  17. Section 5: Write code well by default
    1. Chapter 5.1. P.4: Ideally, a program should be statically type safe
      1. Type safety is a security feature of C++
      2. Union
      3. Casting
      4. Unsigned
      5. Buffers and sizes
      6. Summary
    2. Chapter 5.2. P.10: Prefer immutable data to mutable data
      1. The wrong defaults
      2. constness in function declarations
      3. Summary
    3. Chapter 5.3. I.30: Encapsulate rule violations
      1. Hiding the unsightly things in life
      2. Keeping up appearances
      3. Summary
    4. Chapter 5.4. ES.22: Don’t declare a variable until you have a value to initialize it with
      1. The importance of expressions and statements
      2. C-style declaration
      3. Declare-then-initialize
      4. Maximally delayed declaration
      5. Localization of context-specific functionality
      6. Eliminating state
      7. Summary
    5. Chapter 5.5. Per.7: Design to enable optimization
      1. Maximizing the frame rate
      2. Working further from the metal
      3. Optimization through abstraction
      4. Summary
    6. Chapter 5.6. E.6: Use RAII to prevent leaks
      1. Deterministic destruction
      2. Leaking away files
      3. Why are we bothering?
      4. This all seems a bit much: Future possibilities
      5. Where can I get this?
  18. Envoi
  19. Afterword
  20. Index
  21. Code Snippets

Product information

  • Title: Beautiful C++: 30 Core Guidelines for Writing Clean, Safe, and Fast Code
  • Author(s): J. Guy Davidson, Kate Gregory
  • Release date: December 2021
  • Publisher(s): Addison-Wesley Professional
  • ISBN: 9780137647767