Advanced Real-Time Modern C++

Course category
Training area
Course code
AC++11-502
Duration
5 days
Additional information
Available for on-site delivery only.

The term ‘Modern C++’ is used to describe the current best practices for the use of C++.  In some cases, this may mean new capabilities of the language; in other cases it means more effective ways of performing familiar programming tasks.

This advanced course is designed to transition experienced C++ programmers to the latest incarnation of the C++ language.  The focus is to teach good programming practice using Modern C++ and to put the latest features of the language into context.

Course objectives:

  • To provide a deep understanding of the C++ programming language.
  • To give you practical experience of writing Modern C++ on hosted embedded systems
  • To give you the confidence to apply these new concepts to your next project.

Delegates will learn:

  • Modern C++ syntax, semantics and library features
  • The Application Binary Interface (ABI) and memory model of C++
  • Idioms and patterns for building effective C++ programs
  • Real-time and concurrency design issues

Pre-requisites:

  • A good working knowledge of C++ (knowledge of C++11 onwards is useful, but not essential)
  • Some experience of development multi-threaded applications is useful.
  • A working understanding of machine architectures is helpful.

Who should attend:

  • This course is aimed at C++ programmers who are using earlier standards of C++, and experienced C++ programmers who want to extend and expand their C++ skills.

Duration:

  • Five days.

Course materials:

  • Delegate manual
  • Delegate workbook
  • Delegate datakey

Course workshop:

  • Attendees perform hands-on exercises during course practicals.  Approximately 50% of the course is given over to practical work.  The tools used are indicative of current modern working practices in the embedded arena. 

Part 1 - Core concepts

The C++ object model

  • Declaration and definition
  • Brace initialisation syntax
  • ODR-use and 'The One Declaration Rule'
  • Object scope and lifetime
  • The C++ object (memory) model

Expressions

  • Expressions, 
  • l-values and r-values
  • statements, 
  • happens-before / happens-after

User defined types

  • Aggregate types – structs
  • Brace elision
  • Classes
  • Non-Static Data Member Initialisers
  • Delegating constructors
  • std::initializer_list

Functions

  • Function call ABIs
  • Input, Output and Input-Output parameters
  • const correctness
  • Copy elision
  • Attributes

Type deduction

  • Automatic type deduction
  • Automatic function return-type deduction
  • Structured bindings
  • Using aliases

Constants

  • Literals
  • Const qualification
  • Constexpr
  • constexpr functions
  • enum class
  • enum underlying type

Connecting objects

  • Unidirectional Associations
  • Bidirectional association
  • Forward declarations

Composition

  • Nested object construction

Creating substitutable types

  • Specialisation vs inheritance
  • Substitution
  • The Liskov Substitution principle
  • The virtual function ABI

Abstract Base Classes

  • The Single Responsibility principle
  • Pure virtual functions
  • Abstract types
  • Dynamic cast

Realising interfaces

  • The Dependency Inversion principle
  • The Interface concept
  • Pure virtual classes
  • The Interface Segregation principle

Part 2 - STL containers

Sequence containers

  • The problems with C-style arrays
  • std::array
  • Dynamic sequence containers
  • Emplacement

Algorithms

  • The iterator model
  • Range-for 
  • Algorithms

Associative containers

  • std::pair
  • Sets and maps
  • Hash-maps - std::unordered_map

Callable objects

  • Lambda expressions
  • The 'block-scoped function' concept
  • Generic lambdas
  • std::function

Variable types

  • Generic structures – std::tuple
  • Nullable types – std::optional
  • Type-safe unions – std::variant
  • The Visitor pattern
  • Type-safe void pointers – std::any

Part 3 - Resource management

Resource management

  • The resource lifetime problem
  • Overloading the copy constructor
  • Overloading the assignment operator
  • The 'Rule of the Big Three'
  • The copy-swap idiom

Move semantics

  • The cost of copying
  • 'Resource pilfering'
  • Move constructors
  • The Rule of Four and A Half
  • Move assignment
  • std::move
  • Compiler overload provision for copy / swap

Smart pointers

  • The problem with raw pointers for memory management
  • std::unique_ptr
  • std::shared_ptr
  • std_weak_ptr

Part 4 - Templates

Template functions

  • The problems with function-like macros
  • Template functions
  • Template parameter type deduction
  • The forwarding reference idiom
  • Template function overloading

Template classes

  • Generic classes
  • Template type deduction
  • Template deduction guidelines

Templates and polymorphism

  • The cost of virtual interfaces
  • Policy patterns

Perfect forwarding

  • Variadic templates
  • std::forward
  • std::forward vs std::move

Conditional coding

  • Condition compilation with the pre-processor
  • Template class explicit and partial specialisation
  • Compile-time function selection (SFINAE)
  • Compile-time implementation selection - constexpr-if

Part 5 - Concurrency

Threading

  • Concurrency vs parallelism
  • std::thread
  • Run policies
  • Polymorphic threads
  • Waiting for threads to finish
  • Detaching threads

Mutual exclusion

  • Race conditions
  • Mutual exclusion
  • The scope-locked idiom
  • std::lock_guard and std::unique_lock

Atomic types

  • Shared objects in multiprocessor environments
  • Why volatile is inappropriate
  • Atomic types
  • Load-acquire / Store-release barriers
  • When atomic types are inadequate

Monitors

  • Condition variables
  • The Guarded Suspension pattern

Asynchronous tasks

  • The Asynchronous Message pattern
  • The Promise / Future pattern
  • Packaged tasks
  • std::async
  • Throwing exceptions between threads
  • Launch policies

Appendices

Appendix - User defined literals

  • 'Rommable' types
  • operator ""

Appendix - Exception handling

  • Error handling strategies
  • Throwing / catching exceptions
  • Building an exception hierarchy
  • Standard library exceptions
  • Specifying your exception contract

Appendix - Regular expressions

  •  Regular expressions
  • Regex syntax
  • Searching using regexes
  • Complete and partial matches

Appendix - Container memory allocators

  • Reserving memory on a container
  • The allocator interface
  • Memory resources
  • Polymorphic allocators

Appendix - The C++ build process

  • The seven stages of compilation
  • Object files
  • Imports and Exports tables
  • Linkage
  • ELF files
  • Object conversion for embedded systems