46,44 €
A comprehensive guide with extensive coverage on concepts such as OOP, functional programming, generic programming, and STL along with the latest features of C++
Key Features
Book Description
C++ is a general-purpose programming language designed with the goals of efficiency, performance, and flexibility in mind. Design patterns are commonly accepted solutions to well-recognized design problems. In essence, they are a library of reusable components, only for software architecture, and not for a concrete implementation.
The focus of this book is on the design patterns that naturally lend themselves to the needs of a C++ programmer, and on the patterns that uniquely benefit from the features of C++, in particular, the generic programming. Armed with the knowledge of these patterns, you will spend less time searching for a solution to a common problem and be familiar with the solutions developed from experience, as well as their advantages and drawbacks. The other use of design patterns is as a concise and an efficient way to communicate. A pattern is a familiar and instantly recognizable solution to specific problem; through its use, sometimes with a single line of code, we can convey a considerable amount of information. The code conveys: "This is the problem we are facing, these are additional considerations that are most important in our case; hence, the following well-known solution was chosen."
By the end of this book, you will have gained a comprehensive understanding of design patterns to create robust, reusable, and maintainable code.
What you will learn
Who this book is for
This book is for experienced C++ developers and programmers who wish to learn about software design patterns and principles and apply them to create robust, reusable, and easily maintainable apps.
Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:
Seitenzahl: 750
Veröffentlichungsjahr: 2019
Copyright © 2019 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
Commissioning Editor: Richa TripathiAcquisition Editor: Shriram ShekharContent Development Editor: Manjusha MantriTechnical Editor: Royce John Copy Editor: Safis EditingProject Coordinator: Prajakta NaikProofreader: Safis EditingIndexer: Tejal Daruwale SoniGraphics: Jisha ChirayilProduction Coordinator: Aparna Bhagat
First published: January 2019
Production reference: 1280119
Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.
ISBN 978-1-78883-256-4
www.packtpub.com
Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.
Spend less time learning and more time coding with practical eBooks and videos from over 4,000 industry professionals
Improve your learning with skill plans designed especially for you
Get a free eBook or video every month
Mapt is fully searchable
Copy and paste, print, and bookmark content
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.packt.com and, as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.packt.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.
Fedor G. Pikus is a chief engineering scientist in the Design-to-Silicon division of Mentor Graphics (a Siemens business), and is responsible for the long-term technical direction of Calibre products, the design and architecture of software, and research into new software technologies. His earlier positions include senior software engineer at Google and chief software architect at Mentor Graphics. Fedor is a recognized expert on high-performance computing and C++. He has presented his works at CPPCon, SD West, DesignCon, and in software development journals, and is also an O'Reilly author. Fedor has over 25 patents, and over 100 papers and conference presentations on physics, EDA, software design, and C++.
Cale Dunlap has been writing code in various languages since high school, when he wrote his first video game mod for Half-Life in 1999. In 2002, he contributed to the semi-popular Firearms mod for Half-Life and eventually helped bring that same video game mod to the Source Engine as Firearms—Source. He's earned an associate's degree in computer information systems and a bachelor's degree in game and simulation programming. He's worked professionally as a software developer for small companies since 2005, contributing to software ranging from web applications to military simulations. He currently works as a senior interactive developer for a creative agency based in Orange County, California, called Column Five.
If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.
Title Page
Copyright and Credits
Hands-On Design Patterns with C++
About Packt
Why subscribe?
Packt.com
Contributors
About the author
About the reviewer
Packt is searching for authors like you
Preface
Who this book is for
What this book covers
To get the most out of this book
Download the example code files
Conventions used
Get in touch
Reviews
An Introduction to Inheritance and Polymorphism
Classes and objects
Inheritance and class hierarchies
Polymorphism and virtual functions
Multiple inheritance
Summary
Questions
Further reading
Class and Function Templates
Templates in C++
Function templates
Class templates
Variable template
Non-type template parameters
Template instantiations
Function templates
Class templates
Template specializations
Explicit specialization
Partial specialization
Template function overloading
Variadic templates
Lambda expressions
Summary
Questions
Further reading
Memory Ownership
Technical requirements
What is memory ownership?
Well-designed memory ownership
Poorly designed memory ownership
Expressing memory ownership in C++
Expressing non-ownership
Expressing exclusive ownership
Expressing transfer of exclusive ownership
Expressing shared ownership
Summary
Questions
Further reading
Swap - From Simple to Subtle
Technical requirements
Swap and the standard template library 
Swap and STL containers
Non-member swap
Swapping like the standard
When and why to use swap
Swap and exception safety
Other common swap idioms
How to implement and use swap correctly
Implementing swap
Using swap correctly
Summary
Questions
A Comprehensive Look at RAII
Technical requirements
Resource management in C++
Installing the microbenchmark library
Installing Google Test
Counting resources
Dangers of manual resource management
Manual resource management is error-prone
Resource management and exception safety
The RAII idiom
RAII in a nutshell
RAII for other resources
Releasing early
Careful implementation of  Resource Acquisition is Initialization objects
Downsides of RAII
Summary
Questions
Further reading
Understanding Type Erasure
Technical requirements
What is type erasure?
Type erasure by example
How is type erasure implemented in C++?
Very old type erasure
Object-oriented type erasure
The opposite of the type erasure
Type erasure in C++
When to use type erasure, and when to avoid it
Type erasure and software design
Installing the micro-benchmark library
The overhead of type erasure
Summary
Questions
SFINAE and Overload Resolution Management
Technical requirements
Overload resolution and overload sets
C++ function overloading
Template functions
Type substitution in template functions
Type deduction and substitution
Substitution failure
Substitution Failure Is Not An Error
Taking control of overload resolution
Basic SFINAE
Advanced SFINAE
Advanced SFINAE revisited
The ultimate SFINAE
Summary
Questions
Further reading
The Curiously Recurring Template Pattern
Technical requirements
Wrapping your head around CRTP
What is wrong with a virtual function?
Introducing CRTP
CRTP and static polymorphism
Compile-time polymorphism
The compile-time pure virtual function
Destructors and polymorphic deletion
CRTP and access control
CRTP as a delegation pattern
Expanding the interface
Summary
Questions
Named Arguments and Method Chaining
Technical requirements
The problem with arguments
What's wrong with many arguments
Aggregate parameters
Named arguments in C++
Method chaining
Method chaining and  named arguments
Performance of the named arguments idiom
General method chaining
Method chaining versus method cascading
General method chaining
Method chaining in class hierarchies
Summary
Questions
Local Buffer Optimization
Technical requirements
The overhead of small memory allocations
The cost of memory allocations
Introducing local buffer optimization
The main idea
Effect of local buffer optimization
Additional optimizations
Local buffer optimization beyond strings
Small vector
Type-erased and callable objects
Local buffer optimization in the C++ library
Downsides of local buffer optimization
Summary
Questions
Further reading
ScopeGuard
Technical requirements
Error handling and Resource Acquisition Is Initialization
Error safety and exception safety
Resource Acquisition Is Initialization 
The ScopeGuard pattern
ScopeGuard basics
Generic ScopeGuard
ScopeGuard and exceptions
What must not throw an exception
Exception-driven ScopeGuard
Type-erased ScopeGuard
Summary
Questions
Friend Factory
Technical requirements
Friends in C++
How to grant friendship in C++
Friends versus member functions
Friends and templates
Friends of template classes
The template friend factory
Generating friends on demand
The friend factory and the Curiously Recurring Template Pattern 
Summary
Questions
Virtual Constructors and Factories
Technical requirements
Why constructors cannot be virtual
When does an object get its type?
The Factory pattern
The basics of the Factory method
Arguments for factory methods
Dynamic type registry
Polymorphic factory
Factory-like patterns in C++
Polymorphic copy
CRTP Factory and return types
CRTP Factory with less copy-paste
Summary
Questions
The Template Method Pattern and the Non-Virtual Idiom
Technical requirements
The Template Method pattern
The Template Method in C++
Applications of the Template Method
Pre-and post-conditions and actions
The Non-Virtual Interface
Virtual functions and access
The NVI idiom in C++
A note about destructors
Drawbacks of the Non-Virtual Interface
Composability
The Fragile Base Class problem
Summary
Questions
Further reading
Singleton - A Classic OOP Pattern
Technical requirements
The singleton pattern – what is it and what is it for?
What is a singleton?
When to use the singleton
Types of singletons
Static singleton
Meyers' Singleton
Leaky singletons
Summary
Questions
Policy-Based Design
Technical requirements
Strategy pattern and policy-based design
Foundations of policy-based design
Implementation of policies
Use of policy objects
Advanced policy-based design
Policies for constructors
Policies for test
Policy adapters and aliases
Using policies to control the public interface
Rebinding policies
Recommendations and guidelines
Strengths of the policy-based design
Disadvantages of policy-based design
Guidelines for policy-based designs
Almost policy-based approach
Summary
Questions
Adapters and Decorators
Technical requirements
The decorator pattern
Basic decorator pattern
Decorators the C++ way
Polymorphic decorators and their limitations
Composable decorators
The Adapter pattern
Basic Adapter pattern
Function adapters
Compile-time adapters
Adapter versus policy
Summary
Questions
The Visitor Pattern and Multiple Dispatch
Technical requirements
The Visitor pattern
What is the Visitor pattern?
Basic Visitor in C++
Visitor generalizations and limitations
Visiting complex objects
Visiting composite objects
Serialization and deserialization with Visitor
Acyclic Visitor
Visitors in modern C++
Generic Visitor
Lambda Visitor
Generic Acyclic Visitor
Compile-time Visitor
Summary
Questions
Assessments
Chapter 1
Chapter 2
Chapter 3
Chapter 4
Chapter 5
Chapter 6
Chapter 7
Chapter 8
Chapter 9
Chapter 10
Chapter 11
Chapter 12
Chapter 13
Chapter 14
Chapter 15
Chapter 16
Chapter 17
Chapter 18 
Other Books You May Enjoy
Leave a review - let other readers know what you think
Another book on design patterns in C++? Why that, and why now? Hasn't everything there is to know about design patterns been written already?
There are several reasons why yet another book on design patterns has been written, but first of all, this is very much a C++ book—this is not a book on design patterns in C++ but a book on design patterns in C++, and the emphasis sets it apart. C++ has all the capabilities of a traditional object-oriented language, so all the classic object-oriented design patterns, such as Factory and Strategy, can be implemented in C++. A few of those are covered in this book. But the full power of C++ is realized when you utilize its generic programming capabilities. Remember that design patterns are frequently occurring design challenges and the commonly accepted solution—both sides are equally important in a pattern. It stands to reason that when new tools become available, new solutions become possible. Over time, the community settles on some of these solutions as the most advantageous overall, and a new variation of an old design pattern is born—the same challenge, but a different preferred solution. But expanding capabilities also open up new frontiers—with new tools at our disposal, new design challenges arise.
In this book, we focus on design patterns where C++ has something essential to add to at least one of the two sides of the pattern. On the one hand, we have patterns such as Visitor, where the generic programming capabilities of C++ allow for a better solution. That better solution was made possible by new features added in recent versions of the language, from C++11 to C++17. On the other hand, generic programming is still programming (only the execution of the program happens at compile time); programming requires design, and design has common challenges that are not all that dissimilar to the challenges of traditional programming. Thus, many of the traditional patterns have their twins, or at least close siblings, in generic programming, and we largely focus on those patterns in this book. A prime example is the Strategy pattern, better known in the generic programming community by its alternative name, the Policy pattern. Finally, a language as complex as C++ is bound to have a few idiosyncrasies of its own that often lead to C++, specific challenges that have common, or standard, solutions. While not quite deserving of being called patterns, these C++-specific idioms are also covered in this book.
All that said, there are three main reasons why this book has been written:
To cover C++, specific solutions for otherwise general,
classic
design patterns
To show C++, specific pattern variants that occur when old design challenges arise in the new domain of generic programming
To keep our patterns up to date with the language's evolution
This book is intended for C++ programmers who want to learn from the wisdom of the community—from commonly-recognized good solutions to frequently occurring design problems. Another way to put it is that this book is a way for a programmer to learn from someone else's mistakes.
This is not a learn C++ book; the target audience is mostly programmers who are reasonably familiar with the tools and the syntax of the language, and who are more interested in learning how and why these tools should be used. However, this book will also be useful for programmers wanting to learn more about C++, but wishing that their study could be guided by concrete and practical examples (for such programmers, we recommend having a C++ reference book close to hand as well). Finally, programmers who want to learn not just what's new in C++11, C++14, and C++17, but what all these new features can be used for, will hopefully find this book illuminating as well.
Chapter 1, An Introduction to Inheritance and Polymorphism, provides a brief overview of the object-oriented features of C++. This chapter is not intended as a reference for object-oriented programming in C++, but, rather, highlights the aspects of it that are important for the subsequent chapters.
Chapter 2, Class and Function Templates, provides an overview of the generic programming facilities of C++—class templates, function templates, and lambda expressions. This chapter covers template instantiations and specializations, along with template function argument deduction and overload resolution, and prepares you for more complex uses of templates in later chapters.
Chapter 3, Memory Ownership, describes modern idiomatic ways of expressing different kinds of memory ownership in C++. This is a collection of conventions or idioms—the compiler does not enforce these rules, but programmers will find it easier to understand each other if they use the shared idiomatic vocabulary.
Chapter 4, Swap - From Simple to Subtle, explores one of the most basic C++ operations, the swap, or exchange, of two values. This operation has surprisingly complex interactions with other C++ features that are discussed in the chapter.
Chapter 5, A Comprehensive Look at Resource Acquisition is Initialization, explores in detail one of the fundamental concepts of C++, that of resource management, and introduces what may be the most popular C++ idiom, RAII, which is the standard C++ approach to managing resources.
Chapter 6, Understanding Type Erasure, provides insight into a C++ technique that has been available in C++ for a long time, but has grown in popularity and importance since the introduction of C++11. Type erasure allows the programmer to write abstract programs that do not explicitly mention certain types.
Chapter 7, SFINAE and Overload Resolution Management, discusses SFINAE—a C++ idiom that is, on the one hand, essential to the use of templates in C++ and just happens transparently, while on the other hand, requires a very thorough and subtle understanding of C++ templates when used purposefully.
Chapter 8, The Curiously Recurring Template Pattern, describes a mind-wrapping template-based pattern that combines the benefits of object-oriented programming with the flexibility of templates. The chapter explains the pattern and teaches you how to use it properly to solve practical problems. Lastly, this chapter prepares you for recognizing this pattern in later chapters.
Chapter 9, Named Arguments and Method Chaining, covers an unusual technique for calling functions in C++, using named arguments instead of positional ones. This is another one of those idioms we use implicitly in every C++ program, but its explicit purposeful use takes some thought.
Chapter 10, Local Buffer Optimization, is the only purely performance-oriented chapter in this book. Performance and efficiency are critical considerations that influence every design decision that affects the language itself—there is not a feature in the language that was not reviewed from the point of view of efficiency before being accepted into the standard. It is only fair that a chapter is dedicated to a common idiom used to improve the performance of C++ programs.
Chapter 11, ScopeGuard, introduces an old C++ pattern that has changed almost beyond recognition with the recent versions of C++. The chapter teaches you about a pattern for easily writing exception-safe, or, more generally, error-safe code in C++.
Chapter 12, Friend Factory, describes another old pattern that finds new uses in modern C++. This pattern is used to generate functions associated with templates, such as arithmetic operators for every type generated by a template.
Chapter 13, Virtual Constructors and Factories, covers another classic object-oriented programming pattern as applied to C++, the Factory pattern. In the process, the chapter also shows you how to get the appearance of polymorphic behavior from C++ constructors, even though constructors cannot be virtual.
Chapter 14, The Template Method Pattern and the Non-Virtual Idiom, describes an interesting crossover between a classic object-oriented pattern, the template, and a very C++-centric idiom. Together, they form a pattern that describes the optimal use of virtual functions in C++.
Chapter 15, Singleton, a Classic OOP Pattern, explains another classic object-oriented pattern, the Singleton, as it applies to C++. The chapter discusses when the pattern can be reasonably applied and when it should be avoided, and demonstrates several common implementations of the Singleton.
Chapter 16, Policy-Based Design, covers one of the jewels of C++ design patterns, the Policy pattern (more commonly known as the Strategy pattern), applied at compile time, that is, as a generic programming pattern instead of an object-oriented pattern.
Chapter 17, Adapters and Decorators, discusses the two very broad and closely related patterns as they apply to C++. The chapter considers the use of these patterns in object-oriented designs, as well as in generic programs.
Chapter 18, Visitor and Multiple Dispatch, rounds off our gallery of the classic object-oriented programming patterns with the perennially popular Visitor pattern. The chapter explains the pattern itself, then focuses on the ways that modern C++ makes the implementation of Visitor simpler, more robust, and less error-prone.
To run examples from this book, you will need a computer running Windows, Linux, or macOS (C++ programs can be built on something as small as a Raspberry Pi). You will also need a modern C++ compiler, such as GCC, Clang, Visual Studio, or another compiler that supports the C++ language up to C++17. You will need a basic knowledge of GitHub and Git in order to clone a project with examples.
You can download the example code files for this book from your account at www.packt.com. If you purchased this book elsewhere, you can visit www.packt.com/support and register to have the files emailed directly to you.
You can download the code files by following these steps:
Log in or register at www.packt.com.
Select the SUPPORT tab.
Click on Code Downloads & Errata.
Enter the name of the book in the Search box and follow the onscreen instructions.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR/7-Zip for Windows
Zipeg/iZip/UnRarX for Mac
7-Zip/PeaZip for Linux
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Hands-On-Design-Patterns-with-CPP. In case there's an update to the code, it will be updated on the existing GitHub repository.
We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
There are a number of text conventions used throughout this book.
CodeInText: Indicates code words in the text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example—The overload_set is a variadic class template.
A block of code is set as follows:
template <typename T> T increment(T x) { return x + 1; }
Feedback from our readers is always welcome.
General feedback: If you have questions about any aspect of this book, mention the book title in the subject of your message and email us at [email protected].
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packt.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.
Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.
Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!
For more information about Packt, please visit packt.com.
C++ is, first and foremost, an object-oriented language, and objects are the fundamental building blocks of a C++ program. Class hierarchies are used to express relationships and interactions between different parts of a software system, define and implement the interfaces between components, and organize data and code. While this isn't a book for teaching C++, the aim of this chapter is to give the reader enough knowledge about C++ language features as they relate to classes and inheritance, which will be used in later chapters. To that end, we don't attempt to completely describe the C++ tools for working with classes but introduce the concepts and language constructs that will be used throughout this book.
The following topics will be covered in this chapter:
What are classes and what is their role in C++?
What are class hierarchies and how does C++ use inheritance?
What is runtime polymorphism and how is it used in C++?
While by no means a complete guide or reference to classes and objects, this chapter introduces and explains the concepts the reader will need to understand the examples and explanations in the rest of this book. As our interest is and will be in representing design patterns in C++, this chapter focuses on the proper use of classes and inheritance. We pay particular attention to what relations are expressed through different C++ features—it's through these features we'll express relations and interactions between different components that form a design pattern.
The next chapter will similarly cover knowledge of C++ templates, which will be necessary to understand the subsequent chapters of this book.
What is the importance of objects in C++?
What relation is expressed by public inheritance?
What relation is expressed by private inheritance?
What is a polymorphic object?
For more information on what was covered in this chapter, check out the following links:
C++ Fundamentals
:
https://www.packtpub.com/application-development/c-fundamentals
C++ Data Structures and Algorithms
:
https://www.packtpub.com/application-development/c-data-structures-and-algorithms
Mastering C++ Programming
:
https://www.packtpub.com/application-development/mastering-c-programming
Beginning C++ Programming
:
https://www.packtpub.com/application-development/beginning-c-programming
The template programming features of C++ form a large and complex subject, with many books dedicated exclusively to teaching these features. In this book, we will use many of the advanced C++ generic programming features. How, then, should we prepare the reader to understand these language constructs as they make their appearance throughout this book? This chapter takes an informal approach—instead of precise definitions, we demonstrate the use of templates through examples and explain what the different language features do. If you find your knowledge lacking at this point, you're encouraged to seek a deeper understanding and read one or more of the books dedicated entirely to the C++ language that's focused on explaining its syntax and semantics. Of course, the reader wishing for more precise, formal description is referred to the C++ standard or a reference book.
The following topics will be covered in this chapter:
Templates in C++
Class and function templates
Template instantiations
Template specializations
Overloading of template functions
Variadic templates
Lambda expressions
One of the greatest strengths of C++ is its support for generic programming. In generic programming, the algorithms and data structures are written in terms of generic types that will be specified later. This allows the programmer to implement a function or a class once, and later, instantiate it for many different types. Templates are a C++ feature that allows classes and functions to be defined on generic types. C++ supports three kinds of templates—function, class, and variable templates.
Function templates are generic functions—unlike the regular functions, a template function does not declare its argument types. Instead, the types are template parameters:
template <typename T> T increment(T x) { return x + 1; }
This template function can be used to increment a value of any type by one, for which adding one is a valid operation:
increment(5); // T is int, returns 6increment(4.2); // T is double, return 5.2char c[10];increment(c); // T is char*, returns &c[1]
Most template functions have some limitations on the types that are used as their template parameters. For example, our increment() function requires that the expression x + 1 is valid for the type of x. Otherwise, the attempt to instantiate the template will fail, with a somewhat verbose compilation error.
