C++ - Torsten T. Will - E-Book

C++ E-Book

Torsten T. Will

0,0
58,79 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

This book begins by grounding readers in the essentials of modern C++23, covering syntax, compiling, and core programming concepts. Early chapters introduce building blocks like data types, functions, and statements, ensuring a solid foundation. Readers also learn coding best practices focused on readability and modularization.
As the journey progresses, the focus shifts to object-oriented programming, exploring classes, inheritance, namespaces, and lifecycle management. The text includes advanced topics such as templates, macros, and the integration of C libraries. Readers develop skills in designing secure, maintainable, and extensible code while mastering error handling and testing.
The final sections dive into concurrency, standard library features like containers and algorithms, and advanced stream handling. Practical guidance on thread management, synchronization, and modern concurrency tools prepares readers for real-world applications. Concluding chapters present C++ guidelines, emphasizing sustainable and quality code development, completing a comprehensive path from fundamentals to expert-level mastery.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB

Seitenzahl: 1778

Veröffentlichungsjahr: 2025

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Torsten T. Will

C++

The Comprehensive Guide

Imprint

This e-book is a publication many contributed to, specifically:

Editor   Megan FuerstAcquisitions Editor   Hareem ShafiGerman Edition Editor   Almut PollCopyeditor   Melinda RankinTranslation   Torsten T. WillCover Design   Graham GearyPhoto Credit   Shutterstock.com: 167285333/© titov Dmitriy; Midjourney.comProduction E-Book   Graham GearyTypesetting E-Book   SatzPro, Germany

We hope that you liked this e-book. Please share your feedback with us and read the Service Pages to find out how to contact us.

Library of Congress Cataloging-in-Publication Control Number: 2024039385

ISBN 978-1-4932-2626-9 (print)ISBN 978-1-4932-2627-6 (e-book)ISBN 978-1-4932-2628-3 (print and e-book)

© 2025 by Rheinwerk Publishing Inc., Boston (MA) 1st edition 2025 3rd German edition published 2024 by Rheinwerk Verlag, Bonn, Germany

Notes on Usage

This e-book is protected by copyright. By purchasing this e-book, you have agreed to accept and adhere to the copyrights. You are entitled to use this e-book for personal purposes. You may print and copy it, too, but also only for personal use. Sharing an electronic or printed copy with others, however, is not permitted, neither as a whole nor in parts. Of course, making them available on the internet or in a company network is illegal as well.

For detailed and legally binding usage conditions, please refer to the section Legal Notes.

This e-book copy contains a digital watermark, a signature that indicates which person may use this copy:

Notes on the Screen Presentation

You are reading this e-book in a file format (EPUB or Mobi) that makes the book content adaptable to the display options of your reading device and to your personal needs. That’s a great thing; but unfortunately not every device displays the content in the same way and the rendering of features such as pictures and tables or hyphenation can lead to difficulties. This e-book was optimized for the presentation on as many common reading devices as possible.

If you want to zoom in on a figure (especially in iBooks on the iPad), tap the respective figure once. By tapping once again, you return to the previous screen. You can find more recommendations on the customization of the screen layout on the Service Pages.

Table of Contents

Notes on Usage

Table of Contents

Preface

Part I   Fundamentals

1   C++: The Comprehensive Guide

1.1   New and Modern

1.2   “Dan” Chapters

1.3   Presentation in This Book

1.4   Formatting Used

1.5   Let’s Talk Lingo

2   Programming in C++

2.1   Compiling

2.2   Translation Phases

2.3   Current Compilers

2.3.1   Gnu C++

2.3.2   Clang++ from LLVM

2.3.3   Microsoft Visual C++

2.3.4   Compiler in the Container

2.4   Development Environments

2.5   The Command Line under Ubuntu

2.5.1   Create a Program

2.5.2   Automate with Makefile

2.6   The Visual Studio Code IDE under Windows

2.7   Speed Up the Sample Program

3   C++ for Newcomers

4   The Basic Building Blocks of C++

4.1   A Quick Overview

4.1.1   Comments

4.1.2   The “include” Directive

4.1.3   The Standard Library

4.1.4   The “main()” Function

4.1.5   Types

4.1.6   Variables

4.1.7   Initialization

4.1.8   Output on the Console

4.1.9   Statements

4.2   A Detailed Walkthrough

4.2.1   Spaces, Identifiers, and Tokens

4.2.2   Comments

4.2.3   Functions and Arguments

4.2.4   Side Effect Operators

4.2.5   The “main” Function

4.2.6   Statements

4.2.7   Expressions

4.2.8   Allocations

4.2.9   Types

4.2.10   Variables: Declaration, Definition, and Initialization

4.2.11   Initialize with “auto”

4.2.12   Details on the Include Directive

4.2.13   Modules

4.2.14   Input and Output

4.2.15   The “std” Namespace

4.3   Operators

4.3.1   Operators and Operands

4.3.2   Overview of Operators

4.3.3   Arithmetic Operators

4.3.4   Bit-by-Bit Arithmetic

4.3.5   Composite Assignment

4.3.6   Post- and Preincrement and Post- and Predecrement

4.3.7   Relational Operators

4.3.8   Logical Operators

4.3.9   Pointer and Dereference Operators

4.3.10   Special Operators

4.3.11   Function-Like Operators

4.3.12   Operator Sequence

4.4   Built-In Data Types

4.4.1   Overview

4.4.2   Initialize Built-In Data Types

4.4.3   Integers

4.4.4   Floating-Point Numbers

4.4.5   Truth Values

4.4.6   Character Types

4.4.7   Complex Numbers

4.5   Undefined Behavior

5   Good Code, 1st Dan: Writing Readable Code

5.1   Comments

5.2   Documentation

5.3   Indentations and Line Length

5.4   Lines per Function and File

5.5   Brackets and Spaces

5.6   Names

6   Higher Data Types

6.1   The String Type “string”

6.1.1   Initialization

6.1.2   Functions and Methods

6.1.3   Other String Types

6.1.4   For Viewing Only: “string_view”

6.2   Streams

6.2.1   Input and Output Operators

6.2.2   “getline”

6.2.3   Files for Input and Output

6.2.4   Manipulators

6.2.5   The “endl” Manipulator

6.3   Container and Pointer

6.3.1   Container

6.3.2   Parameterized Types

6.4   The Simple Sequence Containers

6.4.1   “array”

6.4.2   “vector”

6.5   Algorithms

6.6   Pointers and C-Arrays

6.6.1   Pointer Types

6.6.2   C-Arrays

7   Functions

7.1   Declaration and Definition of a Function

7.2   Function Type

7.3   Using Functions

7.4   Defining a Function

7.5   More about Parameters

7.5.1   Call-by-Value

7.5.2   Call-by-Reference

7.5.3   Constant References

7.5.4   Call as Value, Reference, or Constant Reference?

7.6   Functional Body

7.7   Converting Parameters

7.8   Overloading Functions

7.9   Default Parameter

7.10   Arbitrary Number of Arguments

7.11   Alternative Notation for Function Declaration

7.12   Specialties

7.12.1   “noexcept”

7.12.2   Inline Functions

7.12.3   “constexpr”

7.12.4   Deleted Functions

7.12.5   Specialties in Class Methods

8   Statements in Detail

8.1   The Statement Block

8.1.1   Standalone Blocks and Variable Scope

8.2   The Empty Statement

8.3   Declaration Statement

8.3.1   Structured Binding

8.4   The Expression Statement

8.5   The “if” Statement

8.5.1   “if” with Initializer

8.5.2   Compile-Time “if”

8.6   The “while” Loop

8.7   The “do-while” Loop

8.8   The “for” Loop

8.9   The Range-Based “for” Loop

8.10   The “switch” Statement

8.11   The “break” Statement

8.12   The “continue” Statement

8.13   The “return” Statement

8.14   The “goto” Statement

8.15   The “try-catch” Block and “throw”

8.16   Summary

9   Expressions in Detail

9.1   Calculations and Side Effects

9.2   Types of Expressions

9.3   Literals

9.4   Identifiers

9.5   Parentheses

9.6   Function Call and Index Access

9.7   Assignment

9.8   Type Casting

10   Error Handling

10.1   Error Handling with Error Codes

10.2   What Is an Exception?

10.2.1   Throwing and Handling Exceptions

10.2.2   Unwinding the Call Stack

10.3   Minor Error Handling

10.4   Throwing the Exception Again: “rethrow”

10.5   The Order in “catch”

10.5.1   No “finally”

10.5.2   Standard Library Exceptions

10.6   Types for Exceptions

10.7   When an Exception Falls Out of “main”

11   Good Code, 2nd Dan: Modularization

11.1   Program, Library, Object File

11.2   Modules

11.3   Separating Functionalities

11.4   A Modular Example Project

11.4.1   Namespaces

11.4.2   Implementation

11.4.3   Using the Library

Part II   Object-Oriented Programming and More

12   From Structure to Class

12.1   Initialization

12.2   Returning Custom Types

12.3   Methods Instead of Functions

12.4   The Better “print”

12.5   An Output Like Any Other

12.6   Defining Methods Inline

12.7   Separate Implementation and Definition

12.8   Initialization via Constructor

12.8.1   Member Default Values in Declaration

12.8.2   Constructor Delegation

12.8.3   Default Values for Constructor Parameters

12.8.4   Do Not Call the “init” Method in the Constructor

12.8.5   Exceptions in the Constructor

12.9   Struct or Class?

12.9.1   Encapsulation

12.9.2   “public” and “private”, Struct and Class

12.9.3   Data with “struct”, Behavior with “class”

12.9.4   Initialization of Types with Private Data

12.10   Interim Recap

12.11   Using Custom Data Types

12.11.1   Using Classes as Values

12.11.2   Using Constructors

12.11.3   Type Conversions

12.11.4   Encapsulate and Decapsulate

12.11.5   Give Types a Local Name

12.12   Type Inference with “auto”

12.13   Custom Classes in Standard Containers

12.13.1   Three-Way Comparison: The Spaceship Operator

13   Namespaces and Qualifiers

13.1   The “std” Namespace

13.2   Anonymous Namespace

13.3   “static” Makes Local

13.4   “static” Likes to Share

13.5   Remote Initialization or “static inline” Data Fields

13.6   Guaranteed to Be Initialized at Compile Time with “constinit”

13.7   “static” Makes Permanent

13.8   “inline namespace”

13.9   Interim Recap

13.10   “const”

13.10.1   Const Parameters

13.10.2   Const Methods

13.10.3   “const” Variables

13.10.4   Const Returns

13.10.5   “const” Together with “static”

13.10.6   Even More Constant with “constexpr”

13.10.7   “if constexpr” for Compile-Time Decisions

13.10.8   C++20: “consteval”

13.10.9   “if consteval”

13.10.10   Un-“const” with “mutable”

13.10.11   Const-Correctness

13.10.12   Summary

13.11   Volatile with “volatile”

14   Good Code, 3rd Dan: Testing

14.1   Types of Tests

14.1.1   Refactoring

14.1.2   Unit Tests

14.1.3   Social or Solitary

14.1.4   Doppelgangers

14.1.5   Suites

14.2   Frameworks

14.2.1   Arrange, Act, Assert

14.2.2   Frameworks to Choose From

14.3   Boost.Test

14.4   Helper Macros for Assertions

14.5   An Example Project with Unit Tests

14.5.1   Private and Public Testing

14.5.2   An Automatic Test Module

14.5.3   Compile Test

14.5.4   Assemble the Test Suite Yourself

14.5.5   Testing Private Members

14.5.6   Parameterized Tests

15   Inheritance

15.1   Relationships

15.1.1   Has-a Composition

15.1.2   Has-a Aggregation

15.1.3   Is-a Inheritance

15.1.4   Instance-of versus Is-a Relationship

15.2   Inheritance in C++

15.3   Has-a versus Is-a

15.4   Finding Commonalities

15.5   Derived Types Extend

15.6   Overriding Methods

15.7   How Methods Work

15.8   Virtual Methods

15.9   Constructors in Class Hierarchies

15.10   Type Conversion in Class Hierarchies

15.10.1   Converting Up the Inheritance Hierarchy

15.10.2   Downcasting the Inheritance Hierarchy

15.10.3   References Also Retain Type Information

15.11   When to Use Virtual?

15.12   Other Designs for Extensibility

16   The Lifecycle of Classes

16.1   Creation and Destruction

16.2   Temporary: Short-Lived Values

16.3   The Destructor to the Constructor

16.3.1   No Destructor Needed

16.3.2   Resources in the Destructor

16.4   Yoda Condition

16.5   Construction, Destruction, and Exceptions

16.6   Copy

16.7   Assignment Operator

16.8   Removing Methods

16.9   Move Operations

16.9.1   What the Compiler Generates

16.10   Operators

16.11   Custom Operators in a Data Type

16.12   Special Class Forms

16.12.1   Abstract Classes and Methods

16.12.2   Enumeration Classes

17   Good Code, 4th Dan: Security, Quality, and Sustainability

17.1   The Rule of Zero

17.1.1   The Big Five

17.1.2   Helper Construct by Prohibition

17.1.3   The Rule of Zero and Its Application

17.1.4   Exceptions to the Rule of Zero

17.1.5   Rule of Zero, Rule of Three, Rule of Five, Rule of Four and a Half

17.2   Resource Acquisition Is Initialization

17.2.1   An Example with C

17.2.2   Owning Raw Pointers

17.2.3   From C to C++

17.2.4   It Doesn't Always Have to Be an Exception

17.2.5   Multiple Constructors

17.2.6   Multiphase Initialization

17.2.7   Define Where It Is Needed

17.2.8   “new” without Exceptions

18   Specials for Classes

18.1   Allowed to See Everything: “friend” Classes

18.1.1   “friend class” Example

18.2   Nonpublic Inheritance

18.2.1   Impact on the Outside World

18.2.2   Nonpublic Inheritance in Practice

18.3   Signature Classes as Interfaces

18.4   Multiple Inheritance

18.4.1   Multiple Inheritance in Practice

18.4.2   Caution with Pointer Type Conversions

18.4.3   The Observer Pattern as a Practical Example

18.5   Diamond-Shaped Multiple Inheritance: “virtual” for Class Hierarchies

18.6   Literal Data Types: “constexpr” for Constructors

19   Good Code, 5th Dan: Classical Object-Oriented Design

19.1   Objects in C++

19.2   Object-Oriented Design

19.2.1   SOLID

19.2.2   Don't Be STUPID

Part III   Advanced Topics

20   Pointers

20.1   Addresses

20.2   Pointer

20.3   Dangers of Aliasing

20.4   Heap Memory and Stack Memory

20.4.1   The Stack

20.4.2   The Heap

20.5   Smart Pointers

20.5.1   “unique_ptr”

20.5.2   “shared_ptr”

20.6   Raw Pointers

20.7   C-Arrays

20.7.1   Calculating with Pointers

20.7.2   Decay of C-Arrays

20.7.3   Dynamic C-Arrays

20.7.4   String Literals

20.8   Iterators

20.9   Pointers as Iterators

20.10   Pointers in Containers

20.11   The Exception: When Cleanup Is Not Necessary

21   Macros

21.1   The Preprocessor

21.2   Beware of Missing Parenthesis

21.3   Feature Macros

21.4   Information about the Source Code

21.5   Warning about Multiple Executions

21.6   Type Variability of Macros

21.7   Summary

22   Interface to C

22.1   Working with Libraries

22.2   C Header

22.3   C Resources

22.4   “void” Pointers

22.5   Reading Data

22.6   The Main Program

22.7   Summary

23   Templates

23.1   Function Templates

23.1.1   Overloading

23.1.2   A Type as Parameter

23.1.3   Function Body of a Function Template

23.1.4   Values as Template Parameters

23.1.5   Many Functions

23.1.6   Parameters with Extras

23.1.7   Method Templates are Just Function Templates

23.2   Function Templates in the Standard Library

23.2.1   Ranges instead of Containers as Template Parameters

23.2.2   Example: Information about Numbers

23.3   A Class as a Function

23.3.1   Values for a “Function” Parameter

23.3.2   C Function Pointer

23.3.3   The Somewhat Different Function

23.3.4   Practical Functors

23.3.5   Algorithms with Functors

23.3.6   Anonymous Functions: a.k.a. Lambda Expressions

23.3.7   Template Functions without “template”, but with “auto”

23.4   C++ Concepts

23.4.1   How to Read Concepts

23.4.2   How to Use Concepts

23.4.3   How to Write Concepts

23.4.4   Semantic Constraints

23.4.5   Interim Recap

23.5   Template Classes

23.5.1   Implementing Class Templates

23.5.2   Implementing Methods of Class Templates

23.5.3   Creating Objects from Class Templates

23.5.4   Class Templates with Multiple Formal Data Types

23.5.5   Class Templates with Nontype Parameters

23.5.6   Class Templates with Defaults

23.5.7   Specializing Class Templates

23.6   Templates with Variable Argument Count

23.6.1   “sizeof ...” Operator

23.6.2   Convert Parameter Pack to Tuple

23.7   Custom Literals

23.7.1   What Are Literals?

23.7.2   Naming Rules

23.7.3   Literal Processing Phases

23.7.4   Overloading Variants

23.7.5   User-Defined Literal Using Template

23.7.6   Raw or Cooked

23.7.7   Automatically Merged

23.7.8   Unicode Literals

Part IV   The Standard Library

24   Containers

24.1   Basics

24.1.1   Recurring

24.1.2   Abstract

24.1.3   Operations

24.1.4   Complexity

24.1.5   Containers and Their Iterators

24.1.6   Ranges Simplify Iterators

24.1.7   Ranges, Views, Concepts, Adapters, Generators, and Algorithms

24.1.8   Algorithms

24.2   Iterator Basics

24.2.1   Iterators from Containers

24.2.2   More Functionality with Iterators

24.3   Allocators: Memory Issues

24.4   Container Commonalities

24.5   An Overview of the Standard Container Classes

24.5.1   Type Aliases of Containers

24.6   The Sequential Container Classes

24.6.1   Commonalities and Differences

24.6.2   Methods of Sequence Containers

24.6.3   “vector”

24.6.4   “array”

24.6.5   “deque”

24.6.6   “list”

24.6.7   “forward_list”

24.7   Associative and Ordered

24.7.1   Commonalities and Differences

24.7.2   Methods of Ordered Associative Containers

24.7.3   “set”

24.7.4   “map”

24.7.5   “multiset”

24.7.6   “multimap”

24.8   Only Associative and Not Guaranteed

24.8.1   Hash Tables

24.8.2   Commonalities and Differences

24.8.3   Methods of Unordered Associative Containers

24.8.4   “unordered_set”

24.8.5   “unordered_map”

24.8.6   “unordered_multiset”

24.8.7   “unordered_multimap”

24.9   Container Adapters

24.10   Special Cases: “string”, “basic_string”, and “vector<char>”

24.11   Special Cases: “vector<bool>”, “array<bool,n>”, and “bitset<n>”

24.11.1   Dynamic and Compact: “vector<bool>”

24.11.2   Static: “array<bool,n>” and “bitset<n>”

24.12   Special Case: Value Array with “valarray<>”

24.12.1   Element Properties

24.12.2   Initialize

24.12.3   Assignment

24.12.4   Insert and Delete

24.12.5   Accessing

24.12.6   Specialty: Manipulate All Data

24.12.7   Specialty: Slicing and Masking

25   Container Support

25.1   Algorithms

25.2   Iterators and Ranges

25.3   Iterator Adapter

25.4   Algorithms of the Standard Library

25.5   Parallel Execution

25.6   Lists of Algorithm Functions and Range Adapters

25.6.1   Range Adapters and Views

25.6.2   Ranges as Parameters (and More)

25.6.3   List of Nonmodifying Algorithms

25.6.4   Inherently Modifying Algorithms

25.6.5   Algorithms for Partitions

25.6.6   Algorithms for Sorting and Fast Searching in Sorted Ranges

25.6.7   Set Algorithms Represented by a Sorted Range

25.6.8   Heap Algorithms

25.6.9   Minimum and Maximum

25.6.10   Various Algorithms

25.7   Element-Linking Algorithms from “<numeric>” and “<ranges>”

25.8   Copy instead of Assignment: Values in Uninitialized Memory Areas

25.9   Custom Algorithms

25.10   Writing Custom Views and Range Adapters

26   Good Code, 6th Dan: The Right Container for Each Task

26.1   All Containers Arranged by Aspects

26.1.1   When Is a “vector” Not the Best Choice?

26.1.2   Always Sorted: “set”, “map”, “multiset”, and “multimap”

26.1.3   In Memory Contiguously: “vector”, “array”

26.1.4   Cheap Insertion: “list”

26.1.5   Low Memory Overhead: “vector”, “array”

26.1.6   Size Dynamic: All Except “array”

26.2   Recipes for Containers

26.2.1   Two Phases? “vector” as a Good “set” Replacement

26.2.2   Output the Contents of a Container to a Stream

26.2.3   So “array” Is Not That Static

26.3   Implementing Algorithms That Are Specialized Depending on the Container

27   Streams, Files, and Formatting

27.1   Input and Output Concept with Streams

27.2   Global, Predefined Standard Streams

27.2.1   Stream Operators << and >>

27.3   Methods for Stream Input and Output

27.3.1   Methods for Unformatted Output

27.3.2   Methods for Unformatted Input

27.4   Error Handling and Stream States

27.4.1   Methods for Handling Stream Errors

27.5   Manipulating and Formatting Streams

27.5.1   Manipulators

27.5.2   Creating Custom Manipulators without Arguments

27.5.3   Creating Custom Manipulators with Arguments

27.5.4   Directly Change Format Flags

27.6   Streams for File Input and Output

27.6.1   The “ifstream”, “ofstream”, and “fstream” Streams

27.6.2   Connecting to a File

27.6.3   Reading and Writing

27.6.4   Random Access

27.6.5   Synchronized Streams for Threads

27.7   Streams for Strings

27.7.1   Difference from “to_string”

27.7.2   “to_chars” and “format” Are More Flexible than “to_string”

27.7.3   Reading from a String

27.8   Stream Buffers

27.8.1   Access to the Stream Buffer of “iostream” Objects

27.8.2   “filebuf”

27.8.3   “stringbuf”

27.9   “filesystem”

27.10   Formatting

27.10.1   Simple Formatting

27.10.2   Formatting Custom Types

28   Standard Library: Extras

28.1   “pair” and “tuple”

28.1.1   Returning Multiple Values

28.2   Regular Expressions

28.2.1   Matching and Searching

28.2.2   The Result and Parts of It

28.2.3   Found Replacement

28.2.4   Rich in Variants

28.2.5   Iterators

28.2.6   Matches

28.2.7   Options

28.2.8   Speed

28.2.9   Standard Syntax, Slightly Shortened

28.2.10   Notes on Regular Expressions in C++

28.3   Randomness

28.3.1   Rolling a Die

28.3.2   True Randomness

28.3.3   Other Generators

28.3.4   Distributions

28.4   Mathematical

28.4.1   Fraction and Time: “<ratio>” and “<chrono>”

28.4.2   Predefined Suffixes for User-Defined Literals

28.5   System Error Handling with “system_error”

28.5.1   Overview

28.5.2   Principles

28.5.3   “error_code” and “error_condition”

28.5.4   Error Categories

28.5.5   Custom Error Codes

28.5.6   “system_error” Exception

28.6   Runtime Type Information: “<typeinfo>” and “<typeindex>”

28.7   Helper Classes around Functors: “<functional>”

28.7.1   Function Objects

28.7.2   Function Generators

28.8   “optional” for a Single Value or No Value

28.9   “variant” for One of Several Types

28.10   “any” Holds Any Type

28.11   Special Mathematical Functions

28.12   Fast Conversion with “<charconv>”

29   Threads: Programming with Concurrency

29.1   C++ Threading Basics

29.1.1   Starting Pure Threads

29.1.2   Terminating a Thread Prematurely

29.1.3   Waiting for a Thread

29.1.4   Consider Exceptions in the Starting Thread

29.1.5   Passing Parameters to a Thread Function

29.1.6   Moving a Thread

29.1.7   How Many Threads to Start?

29.1.8   Which Thread Am I?

29.2   Shared Data

29.2.1   Data Races

29.2.2   Latch

29.2.3   Barriers

29.2.4   Mutexes

29.2.5   Interface Design for Multithreading

29.2.6   Locks Can Lead to Deadlock

29.2.7   More Flexible Locking with “unique_lock”

29.3   Other Synchronization Options

29.3.1   Call Only Once with “once_flag” and “call_once”

29.3.2   Locking with “recursive_mutex”

29.4   In Its Own Storage with “thread_local”

29.5   Waiting for Events with “condition_variable”

29.5.1   “notify_all”

29.5.2   Synchronize Output

29.6   Waiting Once with “future”

29.6.1   Launch Policies

29.6.2   Wait Until a Certain Time

29.6.3   Exception Handling with “future”

29.6.4   “promise”

29.7   Atomics

29.7.1   Overview of the Operations

29.7.2   Memory Order

29.7.3   Example

29.8   Coroutines

29.8.1   Coroutines in the Compiler

29.8.2   Generator

29.8.3   Coroutines with “promise_type”

29.9   Summary

29.9.1   “<thread>” Header

29.9.2   “<latch>” and “<barrier>” Headers

29.9.3   “<mutex>” and “<shared mutex>” Headers

29.9.4   “<condition variable>” Header

29.9.5   “<future>” Header

29.9.6   “<atomic>” Header

29.9.7   “<coroutine>” Header

30   Good Code, 7th Dan: Guidelines

30.1   Guideline Support Library

30.2   C++ Core Guidelines

30.2.1   Motivation

30.2.2   Type Safety

30.2.3   Use RAII

30.2.4   Class Hierarchies

30.2.5   Generic Programming

30.2.6   Do Not Be Confused by Anachronisms

A   Cheat Sheet

B   The Author

Index

Service Pages

Legal Notes

Preface

Thank you for purchasing this book! There are always modern features in C++ that enable new ways of working and new idioms. If you ask the internet for examples in C++, most sources lean towards the C-like style, which has little to do with the possibilities of modern C++: resource acquisition is initialization (RAII) up front, new concepts and modules and coroutines and ranges. As always, I intend to show you the strengths of C++ in particular—especially where I believe that C++ is ahead of other languages.

In this edition, I am assuming you will use a compiler that is fully capable of C++17. Because all popular compilers now also support C++20, you will have no problems with those features either. In the book, I mostly point out the use of C++20, but at the publisher’s request, I have refrained from specific typographical emphasis on the same. I also describe C++23 features, which I always point out and emphasize, as compiler support for these features is far from complete.

I want to briefly draw your attention to C++17 features that I no longer emphasize, but that I use in almost all listings and that could confuse you if your compiler does not handle them. You still need to write the class template argument deduction for constructors in vector data{1,2,3} as vector<int> data{1,2,3}. You will miss string_view and instead need to write const string&. There are a few more little things that I won’t list here. In C++20, abbreviated function templates have been added, which are extremely useful, but sometimes difficult to point out in listings. If you ever see auto in a function parameter, then it is actually a function template.

However, there are also gaps: Modules unfortunately are not yet fully developed, so I cannot give you many tips on them. And while format is widely supported, this is not yet the case for print.

Of course, there is nothing to be said against writing your program “traditionally.” In short, to me, that means that your program looks more like C than it could look. There’s nothing wrong with that, of course. Some of the best programs are written in C. Nevertheless, if you start a project today and decide to use a programming language translated into machine code, you’d be better off using C++. Because something is happening in the language—or rather, something has happened. With C++23, you have a language that supports you in writing good programs in an up-to-date way. This means that your programs are fast, error resistant, and maintainable. You can program productively.

For this book, I spent a long time thinking about the best way to teach C++. Bjarne Stroustrup gave a keynote speech at CppCon 2017 that had this very topic at its core. He said things there that I think are earth-shattering—at least as far as the C++ world is concerned. He said: “We (teachers) did a poor job of teaching people C++ until C++98.” And he thought about why that was the case. He includes himself in this and summarizes that most C++ books are long, monotonous, and slow. They teach “bottom-up 1990 C++” and use C++11 syntax. And that is wrong. Now, I started writing this book long before Bjarne Stroustrup gave this keynote—and that is precisely why I feel vindicated in the way this book now looks at the end of the work process. I see it the same way, and have tried to present C++ in a different way, rather than from the ground up.

For example, you won’t find pointers explained in this book until well into the book, which may seem like a pretty bold choice. Pointers are important, and C++ is all about addresses—but since C++11, they’re not everything. It is much more important to understand the concept behind pointers, manifested in iterators. Because if you understand the mechanism, you can combine the detail with other things and create something new. I always want to see the why in the foreground.

Stroustrup says in his keynote that the new C++ emphasizes resource security, among other things. He asked, which book emphasized RAII? There are few. You will come across the term RAII several times in this book. He criticizes that many books do not even mention type safety, abstraction, class design, and generic programming. This book does.

However, accuracy and care are also important to me, which is why there is also a more technical section here that deals with the syntax and semantics of the small and large C++ constructs. You can’t skip this in a manual. In a single project, it may be enough to know a single rule about which default operations should be defined for a class. But in an architecture and to understand it, you need to know which default operations exist and how they interact with each other. My approach is therefore to teach you things in three bite-size chunks. The first overview is done in a few pages and gives you the first feel for a C++ program. This is followed by the larger loop, in which I briefly cover almost every language element so that you understand the interactions: you’ll learn about expressions, types, statements, variables, and the standard library. Only in the third round do I go into all these elements in detail in individual chapters. There you will find things explained with background and interaction with the world: bits, bytes, big-endian, floating-point formats, exceptions, classes, and so on.

Especially close to my heart are the chapters on vector, map, and the like—that is, the topic of containers. The containers in the standard library are underestimated and consistently underused. Why is that? Back to Bjarne: Because we haven’t communicated it well enough. I’m trying to take a different approach here. Instead of just listing what containers there are and what interfaces and features they have, I want to draw your attention more to the concepts, especially the similarities and differences between the containers. I don’t want you to memorize all of vector’s methods right from the start, but rather what the containers can do, what they can’t do, and when you should choose which one. I have therefore written a separate chapter on the latter. If you have a problem, you can only find the right container with a reference if you have read and internalized all the container descriptions. I will therefore describe typical problems and present criteria that you can use to select the right container.

And that still doesn’t satisfy me. Knowing C++ doesn’t automatically mean you can program. But anyone who uses the new C++ correctly has understood what it’s all about. And because “what it’s all about” is not only important in C++, but also in other programming languages, it is important to me that you think outside the box—as is also required in the board game of Go. In Go, beginners have kyu ranks, and more advanced players earn their dan ranks. When you follow the advice in the interspersed “dan” chapters that deal with things that occur everywhere in software development, your general programming skills will also improve. No matter whether you program in Java, PHP, or SQL, you need to test and to modularize your code, and in most cases, it doesn’t hurt to know object-oriented programming (OOP). I’ll cover these points and apply them with C++; take them with you on your programming and architecture journey.

During my research on the innovations in C++20 and C++23, I also used the latest techniques. This means that I, as the author, have also consulted an artificial intelligence (AI) assistant from time to time—as you should also do to stay up to date. So it may not be a given that you have decided to pick up a book. But what I’ve realized, especially when working with the pretty impressive AI tools, is that they have their limitations. Especially when it comes to the innovations in C++20 and C++23, AI tools have rarely been able to help me. At the moment, these tools are simply parroting what the internet has been offering since its inception.

Nevertheless, they support us in our daily work. And yes, they amaze me—despite their naivety. I am sure you are aware that you must always remain skeptical of the answers they give you. Always! And that won’t get any easier in the future. Andrei Alexandrescu, who currently works at Nvidia, makes predictions in his very enlightening presentation in the closing keynote speech at Code Europe 2023 that show me where the journey is heading: AI tools will increasingly support us, AI will become more commonplace, and we will notice it less and less—and therefore question it less. But that is, of course, dangerous. Therefore, stay vigilant. And enjoy this book!

Torsten T. WillAugust 2024, Bielefeld

Part I

Fundamentals

You’ll need a compiler or an IDE and must understand how to use them and how they work with your computer.

Then you’ll find out how the C++ language is structured and how you can put the various building blocks together into an executable program.

1    C++: The Comprehensive Guide

With this book on your desk (because it’s probably too heavy for your hands), I hope to provide a work that bridges the gap between textbook and reference. I want to give you a comprehensive guide to programming with C++ to the point that you know where to look next. This is perhaps a somewhat strange approach, but I am deliberately making two compromises here: First, I hope that you already know a little about programming in general and have possibly already gained some experience with the computer’s “way of thinking.” You don’t necessarily need to know C++ itself, which is where this book comes in. Second, there are many details, potential uses, and interactions with other language elements for each language element—and there are many, many of them—so I will describe each language element, but only to a certain depth. However, I embed the descriptions in a context that helps you to develop an understanding. The pure text of the C++ language standard, including the associated standard library, comprises over 2,000 pages—tightly printed and formally written down (the document “N4971” without index). A work such as this book cannot help but present it to you in an understandable but comprehensive way at around 1,000 pages, to be supplemented by a comprehensive reference elsewhere. I recommend reference sites (http://cppreference.com), forums (http://stackoverflow.com), and searching (http://google.com, http://bing.com) on the internet. AI tools might also be useful, but be wary of them.

I have structured this book in such a way that you will first get to know the tool you are working with better. So you will get answers to the questions of what a compiler or a development environment is and how to set up each. Then you will get a quick bird’s-eye overview to make it easier for you to read the later chapters.

Then it gets more detailed. First, you will get to know the language core: How is a C++ program structured, and what elements does your code contain? This is mainly about syntax and semantics; you will also see the built-in data types and learn how the computer calculates with them.

This is followed by a comprehensive description of the standard library with all its tools, but also the concepts that are important for its effective use.

1.1    New and Modern

Through all of this, you will get to know the new, modern C++. Why new? Because a new, modern era has begun for C++ with C++11. C++ has been reworked and is still being reworked. With C++11, C++14, C++17, C++20, and the newest C++23, it has become possible to program in C++ in such a way that you can write more comprehensible, more error-free, and more sustainable programs—if, of course, you use the elements correctly.

But what makes this new or modern C++ programming?

You can program more compactly because the compiler can relieve you of a lot of ballast. Type inference with auto and the range-based for are examples of this.

You will write safer code if you prefer unified initialization with {...}, use fewer raw pointers, use the containers and algorithms of the standard library, and, last but not least, internalize RAII (see Chapter 17, the fourth of the “dan” chapters on good code).

By moving instead of copying, you become more efficient without having to do anything except leave things out (see Chapter 17).

New C++ constructs are an alternative to less secure C means.

When I present examples in this book, I want them to be instructive and meaningful, yet simple, short, and clear in book form. Practical relevance is very important to me. And it can happen that I use one or two patterns that might not have been necessary for the example at hand. For example, you will come across the Pimpl pattern in Chapter 11. In contrast to patterns such as RAII, which are more important in the modern C++, the explanation of these other patterns will usually be brief, because here my consideration tends toward the short. All established patterns and idioms also belong in a book, but this book focuses on the modern ones.

1.2    “Dan” Chapters

At strategically appropriate points, I have included special chapters that deal less with C++ per se, but will still help you when programming with C++. The topics are of a general software development nature such as modularization, testing, and resource management, but applied specifically in the context of C++.

These “dan” chapters are located at points in the book that are thematically related to the surrounding chapters. However, they are deliberately broad in scope and do not just build on the previous chapters. They have more of a general handbook character and invite you to pick up practical tips later on. When working through the chapters sequentially, a bit of jumping ahead is acceptable and even encouraged.

Special attention should be paid to Chapter 29, which, although very compact, contains the most practical tips.

1.3    Presentation in This Book

In this book, I consistently use C++11, C++14, C++17, and C++20 as standards when explaining topics to you. Most new C++ compilers support the majority of these features. I highlight most C++20 features, because you may not be able to use the latest compiler in your project. If you’re working in an environment that requires a very old compiler, you may have to forgo some useful features from the C++ language core and only have access to a limited part of the standard library. Consult your old compiler’s documentation to see what you can use, and check boost to see if your standard library can be extended with it.

I will mention things that you will only find in the latest C++ version, C++23, in the text and mark them in the source code.

1.4    Formatting Used

Listings contain the following elements:

// https://godbolt.org/z/jrqEGvh1M#include <iostream> // cout#include <memory> // make_sharedintmain() { // a comment std::cout << "Blopp\n"; // highlighted type feh-ler(args); // line with an errorifconsteval { // point out C++23 featuressin(55); }for(;;) break; // other marker, for distinction or highlighting}

Listing 1.1     A small formatting example.

Boxes

Boxes contain important things that you should remember.

[Übung]  Bars

The insertions marked with a bar usually contain further information. At the beginning of most chapters, you will find a chapter telegram with terms introduced with this marking.

When I use a name for a sequence of symbols in the text, I try to include the sequence of symbols directly after it. I sometimes would have found this helpful when reading other books. I don’t bracket the symbol with quotation marks “” because in many cases I find this cluttering and sometimes even confusing. Here is an example: you write strings in double quotation marks ", use a reference &, use round brackets (), and angle brackets <> and put a comma , between parameters.

Sample Material for Download

You can download program examples and listings at www.rheinwerk-computing.com/5927.

If you have any questions or comments, or if a discussion would help you, you can reach me at http://cpp11.generisch.de or by email at [email protected].

1.5    Let’s Talk Lingo

In the German edition of this book, there was an explanation here about why I prefer English terms over German ones in many cases. We don’t have that issue in this edition. However, we have a different one: One reason that I prefer to use English technical terms in the German text is to highlight them as C++ language constructs. So I can write “Konzept” when I mean a general principle and “concept” when I refer to C++ concepts. To maintain this clarity in this edition, I need alternative formulations. I hope I have succeeded in this.

For some things, in addition, it is necessary to define terms. Especially in the context of C++-specific terms, I try to stick to one term for this book when several terms are common for one thing. Some mean the same thing, and for others it is important not to confuse them with counterparts. Here is a short list of important aliases that you might find elsewhere:

Destructor luckily has none.

Copy constructor can be abbreviated to copy-c’tor and means T(const T&).

Move constructor might be a movator or T(T&&).

Assignment operator or copy operator instead of copy-assignment operator, copy-assign operator, or T::operator=(const T&).

Move operator instead of move-assign operator or T::operator=(T&&).

Apart from that, I try above all to use clear language throughout. If I haven't quite struck the perfect balance between clarity and style, I hope you'll forgive me.

2    Programming in C++

C++ is a programming language for many purposes. In general, it can be used for almost anything. Due to its focus on performance and interoperability, it is often used in system programming. Operating systems, drivers, and other machine-related programs are often written in C++.

Perhaps you come from Java, C#, or JavaScript. Then you are already familiar with programming. Nevertheless, I would like to introduce you to some special features of C++ that may not be clear to you at first glance:

C++ is translated into machine code.JavaScript is interpreted, and Java is translated into an intermediate code, which is then interpreted. C++ is translated by the compiler directly into the language spoken by the machine.[ 1 ]

C++ is type safe.C is not type safe to this extent, nor is Python or JavaScript.

C++ is generic.You use templates to write generally valid procedures for several data types. This is more difficult in C. In Java, you have generics, but they are not as powerful. The prototype-based class concept of JavaScript and Python allows similar results but takes a different approach.

C++ allows metaprogramming.You can write programs that are executed at compile time.

C++ is an ISO standard.This means that a global international committee decides on the language. Java is mainly backed by Oracle, Python by the “community”.

The most important difference, however, is that in C++ you can choose the best of different paradigms to achieve your goal. However, you do not have to follow any of the paradigms. If you want object orientation through inheritance and dynamic polymorphism as in Java, this is also available in C++, but you can also program without it. If you prefer static coupling via traits, which could be informally called static polymorphism, this is also possible in C++ and is used in abundance in the standard library, but you can also make full use of virtual methods instead. If you like functional approaches, you are better off with C++ with functors, lambdas, and pipelines on views than with Java, but you can also do without them. You can even shift a lot of the execution time to the compile time and thus save users waiting time by assigning more tasks to the compiler with metaprogramming—but you can also do without this if it is not important to you.

2.1    Compiling

When you write a C++ program, this means that you write source code as text, which C++ tools translate into an executable program. When we talk about these tools, we often refer to the compiler, but in reality we mean several tools. I want to be precise in this section and tell you what the different tools do. Later, I will group them together again under the not quite correct term compiler.

One of the reasons for this unclear naming is that nowadays the tools are rarely separate programs. They are often just phases ofa single program. And indeed, Figure 2.1 only reflects a simplified process.

Figure 2.1     The phases of compilation from source code to executable program.

I have left out the optimizations and the fact that a program uses additional libraries (dynamic libraries) when you run it.

This entire process is either initiated from the integrated development environment (IDE) or executed manually on the command line. Manually is actually an exaggeration here as very often a tool is also used in this process, called the build tool. It is quite common to have Makefiles. These are text files that contain the components that belong to the program and instructions for how to produce them from your source code.

Later in the chapter, we will build a small program with an IDE as well as execute it on the command line using a Makefile.

2.2    Translation Phases

To ultimately turn the source code you write into an executable program, the compiler suite performs several phases. Nowadays, the suite is often just one program that takes care of everything. It may also be divided into frontend and backend pieces. In the past, the phases were more or less executed by separate programs. The most important phases are as follows:

PreprocessorReads the include files and expands C macros—that is, textually inserts a previous definition instead of the macro name

Lexer and parserTranslates the character strings into tokens—that is, groups characters into semantic units and recognizes, for example, whether a unit is a string, a number, or a function

C++ semanticsTurns templates into real functions and classes and classes into their instances

Intermediate representation (IR)Creates a machine-oriented, yet platform-independent code and optimizes it at a high level

Code generationGenerates platform-dependent machine code in assembly language and optimizes at a low level

Object filesTranslates the assembly language into machine-readable byte sequences, outputs them to object files and static libraries, and adds debug information

LinkCreates an executable file or dynamic library from object files and library files

2.3    Current Compilers

As already mentioned, the term compiler does not cover a single translation program, but the entire tool chain from the preprocessor to the linker. In addition, the standard library is an integral part of C++. So if you install a compiler on your system, you will always receive a standard library with it.

With well-meaning intentions, this book largely refers to the current standard known as C++23. For C++20, the majority is implemented in the current compilers. I emphasize things that belong to C++23 because the language support is still incomplete, but it is improving. If you use the possibilities that have been added since C++11, you will be able to learn the language faster and use it better than was the case with the previous versions up to C++98, for example.

With a modern compiler, C++ is definitely more enjoyable. Fortunately, most compilers are more or less up to date.

2.3.1    Gnu C++

The C++ compiler g++ from the Gnu Compiler Collection (GCC) is the compiler available on most platforms. It is also the testing ground for trying out new things, so you will almost always find new features implemented here first. Today, in the middle of 2024, C++20 is very well implemented. Unfortunately, C++23 still lacks some features, especially for ranges. On Linux, GCC is usually the first choice. Although GCC is widely used, it has a reputation for having a very complex code base. The compiled programs fall behind somewhat in terms of speed compared to paid compilers.

2.3.2    Clang++ from LLVM

As far as the code base is concerned, LLVM with the C++ compiler called Clang++ has a better reputation. The implementation of the C++20 features is exemplary; little is missing from C++23. Some new features are implemented here first. Clang++ is the standard compiler for macOS development. It is available free of charge for Linux but must be installed in addition to an existing standard library, so it is best to install g++ beforehand.

2.3.3    Microsoft Visual C++

Microsoft's product world for C++ consists (together with other tools) of Microsoft Visual C++ (MSVC), the standard library MSVC STL, and the IDEs that integrate them. These are the specialized Microsoft Visual Studio, which is only available for Windows, and the cross-platform Visual Studio Code. MSVC and MSVC STL differ only slightly from other implementations in terms of the implementation of the C++20 standard. Most of the most important features are included. In some C++23 features, this compiler is even ahead of the others.

2.3.4    Compiler in the Container

With a suitable Docker container, you can try out other compilers with your code without installing them on your system and potentially messing it up.

GCC offers a whole range of ready-to-use containers. For example, you can compile a piece of source code with g++ in version 14.1, which already supports some of C++23 (https://hub.docker.com/_/gcc):

docker run --rm -i -t --volume $PWD:/workdir --workdir /workdir gcc:14.1 \ g++ -std=c++23 -Wall -Wextra -pedantic myFile.cpp -o myFile.x

The result can usually be executed directly with ./myfile.x. Sometimes there are dynamic libraries in the container, in which case you must also execute the file in it:

docker run --rm -i -t --volume $PWD:/workdir --workdir /workdir gcc:14.1 \ ./myfile.x

With Clang++, it works the same way, except that you use silkeh/clang:18 as the image for this compiler.

2.4    Development Environments

There are two main ways for you to develop C++ programs:

Command lineYou work on the command line and call the compiler and other tools manually. Later, you will use tools such as Makefiles to automate these tasks. I recommend that you at least try out the command line. On the one hand, you also learn other useful things about programs and programming. On the other hand, it is easier to automate processes on the command line—and that is ultimately what programming is all about.

Integrated development environmentAn IDE that is tailored to your personal needs can increase your productivity immensely, especially later on in your everyday programming life. On the other hand, an IDE can also overwhelm a beginner with its flood of features. There are assistants that try to speed up the introduction. Whether this works depends on your personality. If you are completely unfamiliar with the command line, you can give this a try.

In some cases, the choice of compiler determines the IDE. If you opt for Microsoft, you have a choice of IDE between Visual Studio Code and Visual C++. Visual Studio Code is free, runs on several platforms, and is intended for various languages. For C++, simply install the corresponding plug-in. Visual Studio C++ only runs on Windows, but it specializes in C++. The website currently advertises the 2022 edition. The already very comprehensive basic version, Visual Studio Community, is free of charge. The professional and enterprise editions are subject to a charge.

Figure 2.2Microsoft products for C++ development.

On the Mac, Xcode supplied by Apple is the de facto standard. This gives you the choice between an excellent IDE and a collection of tools for the command line. You can download these from Apple (https://developer.apple.com/xcode). You can currently obtain Xcode 15 with compiler version 15. The compiler without an IDE can also be used under Linux, where the latest version 18 is available (https://releases.llvm.org/).

The GCC is available as an alternative for Unix as well as for Windows and on the Mac. The C++ compiler is called g++—currently in version 14.1. You primarily use it from the command line, but it also integrates into IDEs such as Eclipse CDT, NetBeans, KDevelop, Code::Blocks, Qt Creator, and others. Some of these tools are even available for multiple platforms. If you want to develop with g++ on Windows, then look for the MinGW integration and whether you have to download it separately or whether it is already included (Minimal Gnu for Windows).

Linux Subsystem under Windows

Under Windows, there is an optional Windows Subsystem for Linux (WSL). There you can start a bash shell and have the same commands available as under Ubuntu, for example—including the apt-get installation command. You can then install GCC and many other things under Windows.

A thoroughly commercial but interesting solution is CLion from JetBrains. The IDE is very well thought out and is based on the successful IntelliJ IDEA, which makes it interesting for some Java developers. Its own compiler is a little behind in terms of standards, but you can configure an installed GCC or Clang compiler.

2.6    The Visual Studio Code IDE under Windows

To install Visual Studio Code (VS Code), simply type “vscode download” inthe search bar of your browser and then click the download link that appears. Then download the setup and run it.

Figure 2.3     Visual Studio Code is available for popular operating systems.

You’ll then find the following:

License agreements

An installation location that must be selected

The start menu folder to set

Options such as Add to PATH (available after restart)

You can then start VS Code in the last installation step or simply type “code”and press (Enter) in the Windows search bar.

Visual Studio Code under Linux

VS Code also runs excellently under Linux. Perhaps even a little better as the compiler is typically already installed there and available in the path. Download VS Code from the website and install it. Also install the C/C++ extension. The compiler available in the system will be recognized.

The display language is (probably) initially set to English. If you want to have the IDE use a different language, you can install that language later by pressing (Ctrl)+ (Shift)+(P) and selecting Configure Display Language.

Figure 2.4     You can first change the display language.

If you choose to change the display language, VS Code will restart with the menus in the new language. It is a good idea to follow the installer's recommendation and also to restart Windows once.

Next, install the C/C++ plug-in:

Pressing (Ctrl)+(Shift)+(X) or clicking the four-box icon in the left bar opens the extensions.

Enter “C++” inthe search and the original Microsoft C++ extension will appear in the list. You can choose the pure extension or the extension pack. I myself have opted for the latter. It consists of the actual C++ extension, the CMake extension, and C++ themes.

Figure 2.5     The welcome screen.

Now we still need a C++ compiler. Microsoft recommends that you check whether you already have one installed. We assume that this is not the case. You have a choice between the MinGW g++ or MSVC compiler.

Figure 2.6     Programming languages are supported in VS Code with plug-ins.

We use the MSVC compiler here. It is best to close VS Code. Then download Build Tools for Visual Studio 2022 from https://visualstudio.microsoft.com/downloads/ and install them. In the selection that appears, select Desktop Development with C++ on the left-hand side and at least MSVC and C++-CMake on the right-hand side.

Figure 2.7     The compiler and other tools are installed separately.

When the many packages have been installed, click Start in the installation screen and you will land in the Developer Command Prompt for VS 2022 (the Devconsole). You can close the installer. You can open the Devconsole again and again by entering “Developer Command” in the start bar and selecting Devconsole.

Figure 2.8     The cl compiler is available in the Devconsole.

To start VS Code with the installed compiler, enter “code” in the Devconsole.

Figure 2.9The fully installed IDE with C++ support.

You will see that the C++ plug-in welcomes you with a new button. Click it. After a few seconds, you can click the button labeled Select My Default Compiler. There is actually already a blue Done tick there, but you can easily check the setting.

Figure 2.10     The compiler has been found.

Figure 2.11     Set the default compiler.

Then select cl.exe. This is the compiler that you have already tried out in the DevConsole. You can carry out the further steps of Get Started with C++ Development yourself if you wish. However, I can also show you a different or additional way to a demo C++ program.

Open a terminal with (Ctrl)+(O) in VS Code. You should get a command prompt in your home directory. There, enter mkdir modern101 and cd modern101 in succession to change to a new directory.

Figure 2.12Start a project in a new directory.

Then select the clearly visible Open Folder button in VS Code and select the modern101 folder you have just created. A new project window will open in which you must first agree to the sentence Yes, I trust the authors of this folder (that's you).

Figure 2.13     A new VS Code opens with the fresh project.

You will now see the project area on the left. There you can hover your mouse pointer over MODERN101 to display buttons for creating a new file. You can also select the New File... entry in the welcome area under Start, but one more dialog will appear. The file name should be modern101.cpp. A text editor opens in the right-hand area where you can enter source code. Write your first C++ program here!

Figure 2.14Enter the C++ source code in the editor.

Now you only need to click the triangle in the top-right-hand corner and select C/C++: cl.exe build and debug active file.

A terminal should open in VS Code, in which the program is compiled. Eventually you will see the question, Which Fibonacci number? To test it, enter “45”.

Figure 2.15     Your first executed C++ program.

With the number 45, it takes a while, but then you will see the result in the terminal. On my computer, the calculation takes about a minute. You can also start with a smaller number like 20. If you choose a number larger than 45, you will exceed the capabilities of the program and get nonsensical output.

Note that the number ranges refer to a Win32 application on a 64-bit Windows. The limits may be different on other platforms.

2.7    Speed Up the Sample Program

If the program runs too long for you, then tabulate the intermediate results. This means that you save them in a table-like data structure. The zeroth entry receives the result of fib(0), the first the result of fib(1), and so on. If you want to use fib(n)