Begin your programming journey with C++ , starting with the basics and progressing through step-by-step examples that will help you become a proficient C++ programmer. This book includes new features from the C++20 standard such as modules, concepts, ranges, and the spaceship operator. All you need are Beginning C++20 and any recent C++ compiler and you'll soon be writing real C++ programs. There is no assumption of prior programming knowledge.
All language concepts that are explained in the book are illustrated with working program examples, and all chapters include exercises for you to test and practice your knowledge. Free source code downloads are provided for all examples from the text and solutions to the exercises.
This latest edition has been fully updated to the latest version of the language, C++20, and to all conventions and best practices of modern C++. Beginning C++20 also introduces the elements of the C++ Standard Library that provide essential support for the C++20 language.
What You Will Learn
. Begin programming with the C++20 standard
. Carry out modular programming in C++
. Work with arrays and loops, pointers and references, strings, and more
. Write your own functions, types, and operators
. Discover the essentials of object-oriented programming
. Use overloading, inheritance, virtual functions, and polymorphism
. Write generic function and class templates, and make them safer using concepts
. Learn the ins and outs of containers, algorithms, and ranges
. Use auto type declarations, exceptions, move semantics, lambda expressions, and much more
----------------------------
Who This Book Is For
Programmers new to C++ and those who may be looking for a refresh primer on C++ in general.
Author(s): Ivor Horton, Peter Van Weert
Edition: 6
Publisher: Apress
Year: 2020
Language: English
Tags: c++20 c++
Table of Contents
About the Authors
About the Technical Reviewer
Introduction
Chapter 1: Basic Ideas
Modern C++
Standard Libraries
C++ Program Concepts
Source Files
Comments and Whitespace
Standard Library Modules
Functions
Statements
Data Input and Output
return Statements
Namespaces
Names and Keywords
Classes and Objects
Templates
Code Appearance and Programming Style
Creating an Executable
Procedural and Object-Oriented Programming
Representing Numbers
Binary Numbers
Hexadecimal Numbers
Negative Binary Numbers
Octal Values
Big-Endian and Little-Endian Systems
Floating-Point Numbers
Representing Characters
ASCII Codes
UCS and Unicode
C++ Source Characters
Escape Sequences
Summary
Chapter 2: Introducing Fundamental Types of Data
Variables, Data, and Data Types
Defining Integer Variables
Signed Integer Types
Unsigned Integer Types
Zero Initialization
Defining Variables with Fixed Values
Integer Literals
Decimal Integer Literals
Hexadecimal Literals
Octal Literals
Binary Literals
Calculations with Integers
Compound Arithmetic Expressions
Assignment Operations
The op= Assignment Operators
The sizeof Operator
Incrementing and Decrementing Integers
Postfix Increment and Decrement Operations
Defining Floating-Point Variables
Floating-Point Literals
Floating-Point Calculations
Mathematical Constants
Mathematical Functions
Invalid Floating-Point Results
Pitfalls
Mixed Expressions and Type Conversion
Explicit Type Conversion
Old-Style Casts
Formatting Strings
Formatting Stream Output
String Formatting with std::format()
Format Specifiers
Formatting Tabular Data
Formatting Numbers
Argument Indexes
Finding the Limits
Finding Other Properties of Fundamental Types
Working with Character Variables
Working with Unicode Characters
The auto Keyword
Summary
Chapter 3: Working with Fundamental Data Types
Operator Precedence and Associativity
Bitwise Operators
The Bitwise Shift Operators
Shifting Signed Integers
Logical Operations on Bit Patterns
Using the Bitwise AND
Using the Bitwise OR
Using the Bitwise Complement Operator
Using the Bitwise Exclusive OR
Using the Bitwise Operators: An Example
The Lifetime of a Variable
Global Variables
Enumerated Data Types
Aliases for Data Types
Summary
Chapter 4: Making Decisions
Comparing Data Values
Applying the Comparison Operators
Comparing Floating-Point Values
The Spaceship Operator
Comparison Categories
Named Comparison Functions
The if Statement
Nested if Statements
Character Classification and Conversion
The if-else Statement
Nested if-else Statements
Understanding Nested ifs
Logical Operators
Logical AND
Logical OR
Logical Negation
Combining Logical Operators
Logical Operators on Integer Operands
Logical Operators vs. Bitwise Operators
Short-Circuit Evaluation
Logical XOR
The Conditional Operator
The switch Statement
Fallthrough
Statement Blocks and Variable Scope
Initialization Statements
Summary
Chapter 5: Arrays and Loops
Arrays
Using an Array
Understanding Loops
The for Loop
Avoiding Magic Numbers
Defining the Array Size with the Braced Initializer
Determining the Size of an Array
Controlling a for Loop with Floating-Point Values
More Complex for Loop Control Expressions
The Comma Operator
The Range-Based for Loop
The while Loop
The do-while Loop
Nested Loops
Skipping Loop Iterations
Breaking Out of a Loop
Indefinite Loops
Controlling a for Loop with Unsigned Integers
Arrays of Characters
Multidimensional Arrays
Initializing Multidimensional Arrays
Setting Dimensions by Default
Multidimensional Character Arrays
Allocating an Array at Runtime
Alternatives to Using an Array
Using array Containers
Accessing Individual Elements
Operations on array<>s As a Whole
Conclusion and Example
Using std::vector Containers
Deleting Elements
Example and Conclusion
Summary
Chapter 6: Pointers and References
What Is a Pointer?
The Address-Of Operator
The Indirection Operator
Why Use Pointers?
Pointers to Type char
Arrays of Pointers
Constant Pointers and Pointers to Constants
Pointers and Arrays
Pointer Arithmetic
The Difference Between Pointers
Comparing Pointers
Using Pointer Notation with an Array Name
Dynamic Memory Allocation
The Stack and the Free Store
Using the new and delete Operators
Dynamic Allocation of Arrays
Multidimensional Arrays
Member Selection Through a Pointer
Hazards of Dynamic Memory Allocation
Dangling Pointers and Multiple Deallocations
Allocation/Deallocation Mismatch
Memory Leaks
Fragmentation of the Free Store
Golden Rule of Dynamic Memory Allocation
Raw Pointers and Smart Pointers
Using unique_ptr Pointers
Using shared_ptr Pointers
Understanding References
Defining References
Using a Reference Variable in a Range-Based for Loop
Summary
Chapter 7: Working with Strings
A Better Class of String
Defining string Objects
Operations with String Objects
Concatenating Strings
Concatenating Strings and Characters
Concatenating Strings and Numbers
Accessing Characters in a String
Accessing Substrings
Comparing Strings
Three-Way Comparisons
Comparing Substrings Using compare()
Comparing Substrings Using substr()
Checking the Start or End of a String
Searching Strings
Searching Within Substrings
Searching for Any of a Set of Characters
Searching a String Backward
Modifying a String
Inserting a String
Replacing a Substring
Removing Characters from a String
std::string vs. std::vector
Converting Strings into Numbers
Strings of International Characters
Strings of wchar_t Characters
Objects That Contain Unicode Strings
Raw String Literals
Summary
Chapter 8: Defining Functions
Segmenting Your Programs
Functions in Classes
Characteristics of a Function
Defining Functions
The Function Body
Return Values
How the return Statement Works
Function Declarations
Function Prototypes
Passing Arguments to a Function
Pass-by-Value
Passing a Pointer to a Function
Passing an Array to a Function
const Pointer Parameters
Passing a Multidimensional Array to a Function
Pass-by-Reference
References vs. Pointers
Input vs. Output Parameters
Passing Arrays by Reference
References and Implicit Conversions
Default Argument Values
Multiple Default Parameter Values
Arguments to main()
Returning Values from a Function
Returning a Pointer
Returning a Reference
Returning vs. Output Parameters
Return Type Deduction
Static Variables
Function Overloading
Overloading and Pointer Parameters
Overloading and Reference Parameters
Overloading and const Parameters
Overloading with const Pointer Parameters
Overloading and Reference-to-const Parameters
Overloading and Default Argument Values
Recursion
Basic Examples of Recursion
Recursive Algorithms
The Quicksort Algorithm
The main() Function
The extract_words() Function
The swap() Function
The sort() Functions
The max_word_length() Function
The show_words() Function
Summary
Chapter 9: Vocabulary Types
Working with Optional Values
std::optional
String Views: The New Reference-to-const-string
Using String View Function Parameters
A Proper Motivation
Spans: The New Reference-to-vector or -array
Spans vs. Views
Spans of const Elements
Fixed-Size Spans
Summary
Chapter 10: Function Templates
Function Templates
Creating Instances of a Function Template
Template Type Parameters
Explicit Template Arguments
Function Template Specialization
Function Templates and Overloading
Function Templates with Multiple Parameters
Return Type Deduction in Templates
decltype(auto)
Default Values for Template Parameters
Non-Type Template Parameters
Templates for Functions with Fixed-Size Array Arguments
Abbreviated Function Templates
Limitations to Abbreviated Function Templates
Summary
Chapter 11: Modules and Namespaces
Modules
Your First Module
Export Blocks
Separating Interface from Implementation
Module Implementation Files
Limitations to Implementation Files
Implicit Imports in Implementation Files
Reachability vs. Visibility
Exporting Import Declarations
Managing Larger Modules
Simulating Submodules
Module Partitions
Module Implementation Partitions
Module Interface Partitions
Global Module Fragments
Namespaces
The Global Namespace
Defining a Namespace
Nested Namespaces
Namespaces and Modules
Organizing Larger Namespaces and Modules
Functions and Namespaces
Using Directives and Declarations
Namespace Aliases
Summary
Chapter 12: Defining Your Own Data Types
Classes and Object-Oriented Programming
Encapsulation
Data Hiding
Inheritance
Polymorphism
Terminology
Defining a Class
Creating Objects of a Class
Constructors
Default Constructors
Defining a Class Constructor
Using the default Keyword
Defining Functions Outside the Class
Default Arguments for Constructor Parameters
Using a Member Initializer List
Using the explicit Keyword
Delegating Constructors
The Copy Constructor
Implementing the Copy Constructor
Deleting the Copy Constructor
Defining Classes in Modules
Accessing Private Class Members
The this Pointer
Returning this from a Function
const Objects and const Member Functions
const Member Functions
const Correctness
Overloading on const
Casting Away const
Using the mutable Keyword
Friends
The Friend Functions of a Class
Friend Classes
Arrays of Class Objects
The Size of a Class Object
Static Members of a Class
Static Member Variables
Accessing Static Member Variables
Static Constants
Static Member Variables of the Class Type Itself
Static Member Functions
Destructors
Using Pointers as Class Members
The Truckload Example
The SharedBox Type Alias
Defining the Package Class
Defining the Truckload Class
Traversing the Boxes Contained in a Truckload
Adding and Removing Boxes
Generating Random Boxes
Putting It All Together
Nested Classes
Nested Classes with Public Access
A Better Mechanism for Traversing a Truckload: Iterators
Summary
Chapter 13: Operator Overloading
Implementing Operators for a Class
Operator Overloading
Implementing an Overloaded Operator
Nonmember Operator Functions
Implementing Full Support for an Operator
Operators That Can Be Overloaded
Restrictions and Key Guideline
Operator Function Idioms
Supporting All Comparison Operators
Defaulting Comparison Operators
Overloading the << Operator for Output Streams
Overloading the Arithmetic Operators
Implementing One Operator in Terms of Another
Member vs. Nonmember Functions
Operator Functions and Implicit Conversions
Overloading Unary Operators
Overloading the Increment and Decrement Operators
Overloading the Subscript Operator
Modifying the Result of an Overloaded Subscript Operator
Function Objects
Overloading Type Conversions
Potential Ambiguities with Conversions
Overloading the Assignment Operator
Implementing the Copy Assignment Operator
Copy Assignment vs. Copy Construction
Deleting the Copy Assignment Operator
Assigning Different Types
Summary
Chapter 14: Inheritance
Classes and Object-Oriented Programming
Hierarchies
Inheritance in Classes
Inheritance vs. Aggregation and Composition
Deriving Classes
Protected Members of a Class
The Access Level of Inherited Class Members
Access Specifiers and Class Hierarchies
Choosing Access Specifiers in Class Hierarchies
Changing the Access Specification of Inherited Members
Constructors in a Derived Class
The Copy Constructor in a Derived Class
The Default Constructor in a Derived Class
Inheriting Constructors
Destructors Under Inheritance
The Order in Which Destructors Are Called
Duplicate Member Variable Names
Duplicate Member Function Names
Multiple Inheritance
Multiple Base Classes
Inherited Member Ambiguity
Repeated Inheritance
Virtual Base Classes
Converting Between Related Class Types
Summary
Chapter 15: Polymorphism
Understanding Polymorphism
Using a Base Class Pointer
Calling Inherited Functions
Virtual Functions
Requirements for Virtual Function Operation
Using the override Specifier
Using final
Virtual Functions and Class Hierarchies
Access Specifiers and Virtual Functions
Default Argument Values in Virtual Functions
Using References to Call Virtual Functions
Polymorphic Collections
Destroying Objects Through a Pointer
Virtual Destructors
Converting Between Pointers to Class Objects
Dynamic Casts
Casting Pointers Dynamically
Converting References
Calling the Base Class Version of a Virtual Function
Calling Virtual Functions from Constructors or Destructors
The Cost of Polymorphism
Determining the Dynamic Type
Pure Virtual Functions
Abstract Classes
An Abstract Box Class
Abstract Classes as Interfaces
Summary
Chapter 16: Runtime Errors and Exceptions
Handling Errors
Understanding Exceptions
Throwing an Exception
The Exception-Handling Process
Code That Causes an Exception to Be Thrown
Nested try Blocks
Class Objects as Exceptions
Matching a Catch Handler to an Exception
Catching Derived Class Exceptions with a Base Class Handler
Rethrowing Exceptions
Unhandled Exceptions
Catching All Exceptions
Functions That Don’t Throw Exceptions
The noexcept Specifier
Exceptions and Destructors
Exceptions and Resource Leaks
Resource Acquisition Is Initialization
Standard RAII Classes for Dynamic Memory
Standard Library Exceptions
The Exception Class Definitions
Using Standard Exceptions
Throwing Standard Exceptions Directly
Deriving Your Own Exception Classes
Summary
Chapter 17: Class Templates
Understanding Class Templates
Defining Class Templates
Template Type Parameters
A Simple Class Template
Defining Member Functions of a Class Template
Constructor Templates
The Destructor Template
Subscript Operator Templates
The Assignment Operator Template
Class Template Instantiation
Explicit Template Instantiation
Testing the Array Class Template
Non-Type Class Template Parameters
Templates for Member Functions with Non-Type Parameters
Arguments for Non-Type Parameters
Non-Type Template Arguments vs. Constructor Arguments
Default Values for Template Parameters
Class Template Argument Deduction
Class Template Specialization
Defining a Class Template Specialization
Partial Template Specialization
Class Templates with Nested Classes
Function Templates for Stack Members
Dependent Names Nuisances
Dependent Type Names
Dependent Base Classes
Summary
Chapter 18: Move Semantics
Lvalues and Rvalues
Rvalue References
Moving Objects
Defining Move Members
Move Constructors
Move Assignment Operators
Explicitly Moved Objects
Move-Only Types
Extended Use of Moved Objects
A Barrel of Contradictions
std::move() Does Not Move
An Rvalue Reference Is an Lvalue
Defining Functions Revisited
Pass-by-Rvalue-Reference
The Return of Pass-by-Value
Return-by-Value
Defining Move Members Revisited
Always Add noexcept
Moving Within Standard Library Containers
The “Move-and-Swap” Idiom
Special Member Functions
Default Move Members
The Rule of Five
The Rule of Zero
Summary
Chapter 19: First-Class Functions
Pointers to Functions
Defining Pointers to Functions
Callback Functions for Higher-Order Functions
Type Aliases for Function Pointers
Function Objects
Basic Function Objects
Standard Function Objects
Parameterized Function Objects
Lambda Expressions
Defining a Lambda Expression
Naming a Lambda Closure
Passing a Lambda Expression to a Function Template
Generic Lambdas
The Capture Clause
Capturing by Value
Capturing by Reference
Capturing Specific Variables
Capturing the this Pointer
The std::function<> Template
Summary
Chapter 20: Containers and Algorithms
Containers
Sequence Containers
Arrays
Lists
Deque
Key Operations
Stacks and Queues
LIFO vs. FIFO Semantics
Priority Queues
Associative Containers
Sets
Ordered Sets
Unordered Sets
Maps
Elements of a Map
Counting Words
Iterators
The Iterator Design Pattern
Iterators for Standard Library Containers
Creating and Working with Standard Iterators
Different Flavors of Iterators
Traversing Elements of a Container
Const Iterators
Inserting in and Erasing from Sequence Containers
Altering Containers During Iteration
Iterators for Arrays
Algorithms
A First Example
Finding Elements
Handling Multiple Output Values
The Remove-Erase Idiom
Erase Functions
Sorting
Parallel Algorithms
Ranges and Views
Range-Based Algorithms
Projection
Views
Views vs. Ranges
Range Adaptors
Turning Ranges into Containers
Range Factories
Writing Through a View
Summary
Chapter 21: Constrained Templates and Concepts
Unconstrained Templates
Constrained Templates
Concepts
Concept Definitions and Expressions
Requires Expressions
Simple Requirements
Compound Requirements
Type Requirements and Nested Requirements
Asserting That a Type Models a Concept
Standard Concepts
Requires Clauses
Shorthand Notation
Constrained Function Templates
Constrained Class Templates
Constrained Class Members
Constraint-Based Specialization
Constraining Auto
Summary
Index