Online Sample Chapters
Smart Pointers
Smart Pointers in C++
Downloadable Sample Chapter
Click below for Sample Chapter related to this title:
alexan07.pdf
alexan08.pdf
alexan11.pdf
alexandrescuch1.pdf
alexch1.pdf
Sample Pages
Download the sample pages (includes Chapter 7 and Index)
Table of Contents
Foreword by Scott Meyers.
Foreword by John Vlissides.
Preface.
Acknowledgments.
I. TECHNIQUES.
1. Policy-Based Class Design. The Multiplicity of Software Design.
The Failure of the Do-It-All Interface.
Multiple Inheritance to the Rescue?
Templates Bring Hope.
Policies and Policy Classes.
Enriched Policies.
Destructors of Policy Classes.
Optional Functionality Through Incomplete Instantiation.
Combining Policy Classes.
Customizing Structure with Policy Classes.
Compatible and Noncompatible Policies.
Decomposing a Class in Policies.
Summary.
2. Techniques. Compile-Time Assertions.
Partial Template Specialization.
Local Classes 28 2.4 Mapping Integral Constants to Types.
Type-to-Type Mapping.
Type Selection.
Detecting Convertibility and Inheritance at Compile Time.
A Wrapper Around type_info.
NullType and EmptyType.
Type Traits.
Summary.
3. Typelists. The Need for Typelists.
Defining Typelists.
Linearizing Typelist Creation.
Calculating Length.
Intermezzo.
Indexed Access.
Searching Typelists.
Appending to Typelists.
Erasing a Type from a Typelist.
Erasing Duplicates.
Replacing an Element in a Typelist.
Partially Ordering Typelists.
Class Generation with Typelists.
Summary.
Typelist Quick Facts.
4. Small-Object Allocation. The Default Free Store Allocator.
The Workings of a Memory Allocator.
A Small-Object Allocator.
Chunks.
The Fixed-Size Allocator.
The SmallObjAllocator Class.
A Hat Trick.
Simple, Complicated, Yet Simple in the End.
Administrivia.
Summary.
Small-Object Allocator Quick Facts.
II. COMPONENTS.
5. Generalized Functors. The Command Design Pattern.
Command in the Real World.
C11 Callable Entities.
The Functor Class Template Skeleton.
Implementing the Forwarding Functor::operator().
Handling Functors.
Build One, Get One Free.
Argument and Return Type Conversions.
Handling Pointers to Member Functions.
Binding.
Chaining Requests.
Real-World Issues I: The Cost of Forwarding Functions.
Real-World Issues II: Heap Allocation.
Implementing Undo and Redo with Functor.
Summary.
Functor Quick Facts.
6. Implementing Singletons. Static Data + Static Functions != Singleton.
The Basic C11 Idioms Supporting Singleton.
Enforcing the Singleton's Uniqueness.
Destroying the Singleton.
The Dead Reference Problem.
Addressing the Dead Reference Problem (I):.
Addressing the Dead Reference Problem (II):.
Implementing Singletons with Longevity.
Living in a Multithreaded World.
Putting It All Together.
Working With SingletonHolder.
Summary.
SingletonHolder Class Template Quick Facts.
7. Smart Pointers. Smart Pointers 101.
The Deal.
Smart Pointers' Storage.
Smart Pointer Member Functions.
Ownership-Handling Strategies.
The Address-of Operator.
Implicit Conversion to Raw Pointer Type.
Equality and Inequality.
Ordering Comparisons.
Checking and Error Reporting.
Smart Pointers to const and const Smart Pointers.
Arrays.
Smart Pointers and Multithreading.
Putting It All Together.
Summary.
SmartPtr Quick Facts.
8. Object Factories. The Need for Object Factories.
Object Factories in C11: Classes and Objects.
Implementing an Object Factory.
Type Identifiers.
Generalization.
Minutiae.
Clone Factories.
Using Object Factories with Other Generic Components.
Summary.
Factory Class Template Quick Facts.
CloneFactory Class Template Quick Facts.
9. Abstract Factory. The Architectural Role of Abstract Factory.
A Generic Abstract Factory Interface.
Implementing AbstractFactory.
A Prototype-Based Abstract Factory Implementation.
Summary.
AbstractFactory and ConcreteFactory Quick Facts.
10. Visitor. Visitor Basics.
Overloading: The Catch-All Function.
An Implementation Refinement: The Acyclic Visitor.
A Generic Implementation of Visitor.
Back to the Cyclic Visitor.
Hooking Variations.
Summary.
Visitor Generic Component Quick Facts.
11. Multimethods. What Are Multimethods?
When Are Multimethods Needed?
Double Switch-on-Type: Brute Force.
The Brute-Force Approach Automated.
Symmetry with the Brute-Force Dispatcher.
The Logarithmic Double Dispatcher.
FnDispatcher and Symmetry.
Double Dispatch to Functors.
Converting Arguments: static_cast or dynamic_cast?
Constant-Time Multimethods: Raw Speed.
BasicDispatcher and BasicFastDispatcher as Policies.
Looking Forward.
Summary.
Double Dispatcher Quick Facts.
Appendix A. Minimalist Multithreading Library. A Critique of Multithreading.
Loki's Approach.
Atomic Operations on Integral Types.
Mutexes.
Locking Semantics in Object-Oriented Programming.
Optional volatile Modifier.
Semaphores, Events, and Other Good Things.
Summary.
Bibliography. Index. 0201704315T04062001
Preface
You might be holding this book in a bookstore, asking yourself whether you should buy it. Or maybe you are in your employers library, wondering whether you should invest time in reading it. I know you dont have time, so Ill cut to the chase. If you have ever asked yourself how to write higher-level programs in C++, how to cope with the avalanche of irrelevant details that plague even the cleanest design, or how to build reusable components that you dont have to hack into each time you take them to your next application, then this book is for you.
Imagine the following scenario. You come from a design meeting with a couple of printed diagrams, scribbled with your annotations. Okay, the event type passed between these objects is not char anymore; its int. You change one line of code. The smart pointers to Widget are too slow; they should go unchecked. You change one line of code. The object factory needs to support the new Gadget class just added by another department. You change one line of code.
You changed the design. Compile. Link. Done.
Well, there is something wrong with this scenario, isnt there? A much more likely scenario is this: You come from the meeting in a hurry because you have a pile of work to do. You fire a global search. You perform surgery on code. You add code. You introduce bugs. You remove the bugs . . . thats the way a programmers job is, right? Although this book cannot possibly promise you the first scenario, it is nonetheless a resolute step in that direction. It tries to present C++ as a newly discovered language for software architects.
Traditionally, code is the most detailed and intricate aspect of a software system. Historically, in spite of various levels of language support for design methodologies (such as object orientation), a significant gap persisted between the blueprints of a program and its code because the code must take care of the ultimate details of the implementation and of many ancillary tasks. The intent of the design is, more often than not, dissolved in a sea of quirks.
This book presents a collection of reusable design artifacts, called generic components, together with the techniques that make them possible. These generic components bring their users the well-known benefits of libraries, but in the broader space of system architecture. The coding techniques and the implementations provided focus on tasks and issues that traditionally fall in the area of design, activities usually done before coding. Because of their high level, generic components make it possible to map intricate architectures to code in unusually expressive, terse, and easy-to-maintain ways.
Three elements are reunited here: design patterns, generic programming, and C++. These elements are combined to achieve a very high rate of reuse, both horizontally and vertically. On the horizontal dimension, a small amount of library code implements a combinatorialand essentially open-endednumber of structures and behaviors. On the vertical dimension, the generality of these components makes them applicable to a vast range of programs.
This book owes much to design patterns, powerful solutions to ever-recurring problems in object-oriented development. Design patterns are distilled pieces of good designrecipes for sound, reusable solutions to problems that can be encountered in manycontexts. Design patterns concentrate on providing a suggestive lexicon for designs to be conveyed. They describe the problem, a time-proven solution with its variants, and the consequences of choosing each variant of that solution. Design patterns go above and beyond anything a programming language, no matter how advanced, could possibly express. By following and combining certain design patterns, the components presented in this book tend to address a large category of concrete problems.
Generic programming is a paradigm that focuses on abstracting types to a narrow collection of functional requirements and on implementing algorithms in terms of these requirements. Because algorithms define a strict and narrow interface to the types they operate on, the same algorithm can be used against a wide collection of types. The implementations in this book use generic programming techniques to achieve a minimal commitment to specificity, extraordinary terseness, and efficiency that rivals carefully handcrafted code.
C++ is the only implementation tool used in this book. You will not find in this book code that implements nifty windowing systems, complex networking libraries, or clever logging mechanisms. Instead, you will find the fundamental components that make it easy to implement all of the above, and much more. C++ has the breadth necessary to make this possible. Its underlying C memory model ensures raw performance, its support for polymorphism enables object-oriented techniques, and its templates unleash an incredible code generation machine. Templates pervade all the code in the book because they allow close cooperation between the user and the library. The user of the library literally controls he way code is generated, in ways constrained by the library. The role of a generic component library is to allow user-specified types and behaviors to be combined with generic components in a sound design. Because of the static nature of the technique used, errors in mixing and matching the appropriate pieces are usually caught during compile time.
This books manifest intent is to create generic componentspreimplemented pieces of design whose main characteristics are flexibility, versatility, and ease of use. Generic components do not form a framework. In fact, their approach is complementarywhereas a framework defines interdependent classes to foster a specific object model, generic components are lightweight design artifacts that are independent of each other, yet can be mixed and matched freely. They can be of great help in implementing frameworks.
Audience
The intended audience of this book falls into two main categories. The first category is that of experienced C++ programmers who want to master the most modern library writing techniques. The book presents new, powerful C++ idioms that have surprising capabilities, some of which werent even thought possible. These idioms are of great help in writing high-level libraries. Intermediate C++ programmers who want to go a step further will certainly find the book useful, too, especially if they invest a bit of perseverance. Although pretty hard-core C++ code is sometimes presented, it is thoroughly explained.
The second category consists of busy programmers who need to get the job done without undergoing a steep learning investment. They can skim the most intricate details of implementation and concentrate on using the provided library. Each chapter has an introductory explanation and ends with a Quick Facts section. Programmers will find these features a useful reference in understanding and using the components. The components can be understood in isolation, are very powerful yet safe, and are a joy to use.
You need to have a solid working experience with C++ and, above all, the desire to learn more. A degree of familiarity with templates and the Standard Template Library (STL) is desirable.
Having an acquaintance with design patterns (Gamma et al. 1995) is recommended but not mandatory. The patterns and idioms applied in the book are described in detail. However, this book is not a pattern bookit does not attempt to treat patterns in full generality. Because patterns are presented from the pragmatic standpoint of a library writer, even readers interested mostly in patterns may find the perspective refreshing, if constrained.
Loki
The book describes an actual C++ library called Loki. Loki is the god of wit and mischief in Norse mythology, and the authors hope is that the librarys originality and flexibility will remind readers of the playful Norse god. All the elements of the library live in the namespace Loki. The namespace is not mentioned in the coding examples because it would have unnecessarily increased indentation and the size of the examples. Loki is freely available; you can download it from http://www.awl.com/cseng/titles/0-201-70431-5.
Except for its threading part, Loki is written exclusively in standard C++. This, alas, means that many current compilers cannot cope with parts of it. I implemented and tested Loki using Metrowerks CodeWarrior Pro 6.0 and Comeau C++ 4.2.38, both on Windows. It is likely that KAI C++ wouldnt have any problem with the code, either. As vendors release new, better compiler versions, you will be able to exploit everything Loki has to offer.
Lokis code and the code samples presented throughout the book use a popular coding standard originated by Herb Sutter. Im sure you will pick it up easily. In a nutshell,
Classes, functions, and enumerated types look LikeThis.
Variables and enumerated values look likeThis.
Member variables look likeThis_.
Template parameters are declared with class if they can be only a user-defined type, and with typename if they can also be a primitive type.
Organization
The book consists of two major parts: techniques and components. Part I (Chapters 1 to 4) describes the C++ techniques that are used in generic programming and in particular in building generic components. A host of C++-specific features and techniques are presented: policy-based design, partial template specialization, typelists, local classes, and more. You may want to read this part sequentially and return to specific sections for reference.
Part II builds on the foundation established in Part I by implementing a number of generic components. These are not toy examples; they are components of industrial strength used in real-world applications. Recurring issues that C++ developers face in their day-to-day activity, such as smart pointers, object factories, and functor objects, are discussed in depth and implemented in a generic way. The text presents implementations starting from the needs, the fundamental problems. Instead of explaining what a body of code does, the approach of the book is to discuss problems, take design decisions, and implement those decisions gradually.
Chapter 1 presents policiesa C++ idiom that helps in creating flexible designs.
Chapter 2 discusses general C++ techniques related to generic programming.
Chapter 3 implements typelists, which are powerful type manipulation structures.
Chapter 4 introduces an important ancillary tool: a small-object allocator.
Chapter 5 introduces the concept of generalized functors, useful in designs that use the Command design pattern.
Chapter 6 describes Singleton objects.
Chapter 7 discusses and implements smart pointers.
Chapter 8 describes generic object factories.
Chapter 9 treats the Abstract Factory design pattern and provides implementations of it.
Chapter 10 implements several variations of the Visitor design pattern in a generic manner.
Chapter 11 implements several multimethod engines, solutions that foster various trade-offs.
The design themes cover many important situations that C++ programmers have to cope with on a regular basis. I personally consider object factories (Chapter 8) a cornerstone of virtually any quality polymorphic design. Also, smart pointers (Chapter 7) are an important component of many C++ applications, small and large. Generalized functors (Chapter 5) have an incredibly broad range of applications. Once you have generalized functors, many complicated design problems become very simple. The other, more specialized, generic components, such as Visitor (Chapter 10) or multimethods (Chapter 11) have important niche applications and stretch the boundaries of language support.
0201704315P04062001
Index
A
-
Abstract Factory design pattern, 69, 40-51
-
architectural role of, 219-222
-
basic description of, 219-234
-
implementing, 226-233
-
interface, generic, 223-226
-
quick facts, 233-234
-
AbstractEnemyFactory, 221-222, 224-227
-
AbstractFactory, 219-234
-
AbstractProduct, 209-214, 216-217
-
abstract products, 209-214, 216-217, 222, 231
-
Accept, 240-251, 254
-
AcceptImpl, 252, 256, 259
-
ACE, 309
-
Acquire, 161-162, 305, 306
-
Action, 100
-
Adapter, 284
-
Add, 278-282, 284, 300
-
address-of, 170-171
-
after, 16
-
AbstactFactoryUnit, 223-226
-
Alexandrescu, Andrei, 29
-
algorithms
-
copy, 40
-
compile-time, 76
-
linear search, 56
-
operating on typelists, 76
-
Allocate, 83, 85
-
Allocated, 82
-
allocation, small-object. See also allocators
-
basic description of, 77-96
-
default free store allocators and, 78
-
fixed-size allocators and, 84-87
-
hat trick and, 89-91
-
memory chunks and, 81-84
-
quick facts, 94-95
-
allocators. See also allocation, small-object
-
default free store, 78
-
fixed-size, 84-87
-
memory chunks and, 81-84
-
workings of, 78-79
-
allocChunk_, 85, 87
-
AllowConversion, 192-193
-
ALU (arithmetic logic unit), 303
-
AnotherDerived, 197
-
APIs (application program interfaces), 161, 306
-
Append, 57-58, 76
-
Application, 100
-
arguments, 114-115, 285-290
-
Array policy, 19-20
-
arrays, 19-20, 183-184
-
ArrayStorage, 189-190
-
assert, 193
-
AssertCheck, 193
-
AssertCheckStrict, 193
-
assertions, compile-time, 23-26
-
associative collections, 203
-
AssocVector, 210, 277-278
-
asynchronous execution, 302
-
atexit, 134-139, 142-143, 149
-
ATEXIT_FIXED, 139
-
AtExitFn, 144-145
-
AtomicAdd, 305
-
AtomicAssign, 305
-
AtomicDecrement, 186
-
AtomicIncrement, 186
-
auto_ptr, 108, 159, 170
-
available_, 79
B
-
backEnd_, 281, 294
-
BackendType, 294
-
BadMonster, 219-222
-
BadSoldier, 219-222, 230
-
BadSuperMonster, 219-221
-
BankAccount, 306
-
Bar, 139
-
Base, 63, 90, 91, 176
-
BASE_IF, 37
-
BaseLhs, 272, 299
-
BaseProductList, 227
-
BaseRhs, 272, 284, 299
-
BaseSmartPtr, 46
-
BaseVisitable, 249, 251, 254
-
BaseVisitor, 245, 249-250, 252, 254, 256, 261
-
BaseVisitorImpl, 260, 262
-
BasicDispatcher, 277-284, 292-294, 297-299
-
BasicFastDispatcher, 291-294, 297, 298-299
-
before, 16
-
BinderFirst, 121
-
BindFirst, 121, 127-128
-
binding, 119-121, 127-128
-
BitBlast, 40-41, 44-46
-
blocksAvailable_, 81-83
-
blockSize_, 82
-
bookkeeping data level, 185-187
-
bool, 105, 174-175, 177, 191
-
_buffer, 135
-
bulk allocation, 86
-
butterfly allocation, 86
-
Button, 50, 61-62, 219-221
C
-
callable entities, 103-104
-
callbackMap_, 280
-
callbacks, 103-104, 205, 280-281
-
callbacks_, 205, 281
-
CallbackType, 277, 280, 299
-
CastingPolicy policy, 288, 299
-
CatchAll policy, 260, 262
-
Chain, 122, 128
-
chaining requests, 122
-
char, 35, 38, 114-115
-
checking issues, 181-182
-
checkingImpl, 193
-
Checking policy, 15-16, 188, 193-194
-
chunks, of memory, 81-87
-
chunkSize, 88
-
Circle, 203
-
class(es). See also inheritance; policy classes
-
base, 228
-
client, 153-154
-
decomposing, 19-20
-
derived, 228
-
final, 29
-
generating, with typelists, 64-75
-
-level locking operations, 187
-
local, 28-29
-
object factories and, 200-201
-
visitable, 248-255
-
visitor, 248-255
-
Class, 200
-
ClassLevelLockable, 153, 307-309
-
Clone, 30, 107, 123, 164, 211-213, 230, 232, 234, 284
-
CloneFactory, 214-218
-
clone object factories, 211-215
-
CLOS, 263
-
columns_, 292
-
COM (Component Object Model), 133, 192
-
command(s). See also Command design pattern
-
active, 102
-
forwarding, 102
-
Command, 100
-
Command design pattern, 99-104
-
basic description of, 100-102
-
in the real world, 102-103
-
comparison operators, 178-181
-
compile-time
-
assertions, 23-26
-
detecting convertibility and inheritance at, 34-37
-
CompileTimeChecker, 25-26
-
CompileTimeError, 25
-
COMRefCounted, 192
-
ConcreteCommand, 100, 102
-
ConcreteFact, 232, 234
-
ConcreteFactory, 226-228, 230-231, 233-234
-
ConcreteLifetimeTracker, 144-145
-
concrete products, 222, 227
-
const, 44, 114-115, 182-183
-
constant(s)
-
mapping integral, to types, 29-31
-
-time multimethods, 290-293
-
ConventionalDialog, 219-221
-
conversion
-
argument, 114-115, 285-290
-
binding as, 119-121
-
implicit, to raw pointer types, 171-173
-
return type, 114-114
-
user-defined, 172
-
Conversion policy, 36-37, 188, 192-193
-
convertibility, detecting, at compile time, 35-37
-
copy
-
construction, eliding of, 123
-
deep, 123, 162-164, 192
-
destructive, 168-170
-
on write (COW), 165
-
Copy, 40, 45
-
copy_backward, 144
-
copyAlgo, 45
-
CORBA (Common Object Request Broker Architecture), 115, 133
-
counting, reference, 165-167
-
covariant return types, 212-213
-
Create, 9, 11-12, 14, 31-32, 198, 224, 234
-
CreateButton, 50
-
CreateDocument, 199
-
CreateObject, 208-209
-
CreateScrollBar, 50
-
CreateShape, 205-206
-
CreateShapeCallback, 205
-
CreateStatic, 153
-
CreateT, 223
-
CreateUsingMalloc, 153
-
CreateUsingNew, 153
-
CreateWindow, 50
-
Creation policy, 151, 153
-
Creator policy, 7-9, 11-14, 149, 154, 156
-
cyclic
-
dependencies, 243-248
-
references, 168
-
CyclicVisitor, 255-257, 261
-
Czarnecki, Krzysztof, 54
D
-
dead reference problem, 135-142
-
Deallocate, 82-87
-
deallocChunk_, 86-87
-
deep copy, 123, 163-164, 192
-
DeepCopy, 192
-
DEFAULT_CHUNK_SIZE, 93-94, 95
-
default free store allocator, 78
-
DefaultLifetime, 153
-
DEFAULT_THREADING, 94
-
#define preprocessor directive, 93, 139
-
DEFINE_CYCLIC_VISITABLE, 257
-
DEFINE_VISITABLE, 252, 254, 256
-
delete, 12, 89-91, 94, 108, 132, 143, 159, 172-178
-
delete[], 184, 189-190
-
DeleteChar, 125
-
dependency, circular, 141
-
DependencyManager, 141
-
Deposit, 306
-
dereference, checking before, 182
-
Derived, 90, 197-198
-
DerivedToFront algorithm, 63-65, 76, 272
-
design patterns
-
Abstract Factory pattern, 69, 49-51, 219-234
-
Command pattern, 99-104
-
Double-Checked Locking pattern, 146-147, 149
-
Prototype design pattern, 228-233
-
Strategy design pattern, 8
-
Destroy policy, 20
-
destroyed_, 136, 138
-
_DestroySingleton, 135
-
DestructiveCopy, 192
-
destructors, 12-13
-
detection, dead-reference, 135-137
-
Dialog, 219-221
-
Dijkstra, Edgar, 305-306
-
DisallowConversion, 192-193
-
DispatcherBackend policy, 294
-
DispatchRhs, 269-270
-
Display, 135-142, 169
-
DisplayStatistics, 230
-
do-it-all interface, failure of, 4-5
-
DocElement, 236-248, 249, 251, 256, 259
-
DocElementVisitor, 239-248
-
DocElementVisitor.h, 243-244
-
DoClone, 213
-
DoCreate, 223-224, 227, 232
-
DocStats, 236-237, 240-242, 246-247, 248
-
Document, 198
-
DocumentManager, 198-199
-
DottedLine, 212
-
double, 306
-
Double-Checked Locking pattern, 146-147, 149
-
DoubleDispatch, 267, 268
-
double dispatcher, logarithmic, 263, 276-285, 297-300
-
double switch-on-type, 264-268
-
Dr. Dobb's Journal, 125
-
Drawing, 201-203
-
DrawingDevices, 290
-
DrawingType, 203
-
Dylan, 263
-
dynamic_cast, 238, 243, 246, 251, 255, 267, 285-290, 299
-
cost of, 255-256
-
DynamicCaster, 288, 289
E
-
EasyLevelEnemyFactory, 227, 229, 231
-
Effective C++ (Meyers), 132
-
efficient resource use, 302
-
Eisenecker, Ulrich, 54
-
ElementAt, 20
-
Ellipse, 203, 271, 273
-
else, 238
-
EmptyType, 39-40, 48, 110
-
encapsulation, 99
-
EnforceNotNull, 15, 18
-
enum, 45
-
equality, 173-178
-
erase, 278
-
Erase, 58-59, 76
-
EraseAll, 76, 59
-
error(s)
-
messages, compile-time assertions and, 24
-
reporting, 181-182
-
EventHandler, 71
-
events, 71, 309
-
exceptions, 209
-
Execute, 100, 102
-
Executor, 269-272
-
exists2Way, 36
-
ExtendedWidget, 18, 164
F
-
factor(ies)
-
basic description of, 197-218
-
classes and, 200-201
-
generalization and, 207-210
-
implementing, 201-206
-
need for, 198-200
-
quick facts, 216-217
-
templates, 216-218
-
type identifiers and, 206-207
-
using, with generic components, 215
-
Factory, 207-208, 215-217
-
FactoryErrorImpl, 209
-
FactoryError policy, 208-209, 217-218, 234
-
FactoryErrorPolicy, 217-218, 234
-
FastWidgetPtr, 17
-
Field, 67-70, 74-75
-
Fire, 275, 270, 271
-
firstAvailableBlock_, 81-83
-
FixedAllocator, 80-81, 84-95
-
FnDispatcher, 280-282, 285, 288, 293-294, 299-300
-
FnDoubleDispatcher, 280
-
Foo, 103, 139
-
forwarding functions, cost of, 122-124
-
free, 143, 189-190
-
fun_, 113, 115
-
functionality, optional, through incomplete instantiation, 13-14
-
functions
-
forwarding, cost of, 122-124
-
static, singletons and, 130
-
functor(s)
-
argument type conversions and, 114-115
-
basic description of, 99-128
-
binding and, 119-121
-
chaining requests and, 122
-
command design pattern and, 100-102
-
double dispatch to, 282-285
-
generalized, 99-128
-
handling, 110-112
-
heap allocation and, 124-125
-
implementing Undo and Redo with, 125-126
-
multimethods and, 282-285
-
quick facts, 126-128
-
real-world issues and, 122-125
-
return type conversions and, 114-115
-
Functor1, 106
-
Functor2, 106
-
FunctorDispatcher, 283-285, 288, 293, 299-300
-
FunctorHandler, 110-112, 117-119, 126
-
Functor template, 99-108, 114, 117, 120, 125-126, 215
-
FunctorImpl, 107-112, 123-124, 128, 283, 284
-
FunctorType, 284
-
FunkyDialog, 219-221
G
-
GameApp, 230
-
Gamma, Ralph, 248
-
generalization, 207-210. See also generalized functors
-
generalized functors. See also functors
-
argument type conversions and, 114-115
-
basic description of, 99-128
-
binding and, 119-121
-
chaining requests and, 122
-
Command design pattern and, 100-102
-
handling, 110-112
-
heap allocation and, 124-125
-
implementing Undo and Redo with, 125-126
-
quick facts, 126-128
-
real-world issues and, 122-125
-
return type conversions and, 114-115
-
GenLinearHierarchy, 71-75, 227, 230, 231
-
GenScatterHierarchy, 64-75, 223-226, 227-228
-
geronimosWork, 117
-
GetClassIndex, 292-293
-
GetClassIndexStatic, 292
-
GetImpl, 162, 173, 183, 190
-
GetImplRef, 162, 190
-
GetLongevity, 154
-
GetPrototype, 12, 14
-
Go, 269, 270, 272, 279
-
GoF (Gang of Four) book, 100, 122, 125, 199, 235, 248-249, 255-262
-
granular interfaces, 224
-
GraphicButton, 61-62
-
GUI (graphical user interface), 102
H
-
handles, 161
-
Harrison, Tim, 146
-
Haskell, 263
-
hat trick, 89-91
-
HatchingDispatcher, 272
-
HatchingExecutor, 271
-
HatchRectanglePoly, 279
-
header files
-
DocElementVisitor.h, 243-244
-
Multimethods.h, 294
-
Typelist.h, 51, 55, 75
-
SmallAlloc.h, 93-95
-
heaps, 124-125, 189-190
-
HeapStorage, 189-190
-
hierarchies
-
linear, 70-74
-
scattered, 64-70
-
HTMLDocument, 198
I
-
IdentifierType, 209, 213, 215
-
IdToProductMap, 214
-
#ifdef preprocessor directive, 138-139
-
if-else statements, 29, 267, 268, 270
-
if statements, 238, 267, 305
-
IMPLEMENT_INDEXABLE_CLASS, 293
-
implicit conversion, to raw pointer types, 171-173
-
IncrementFontSize, 240, 241
-
indexed access, 55
-
IndexOf, 56, 76, 275
-
inequality, 173-178
-
inheritance
-
detecting, at compile time, 34-37
-
logarithmic dispatcher and, 279
-
multiple, 5-6
-
INHERITS, 37
-
InIt, 40, 82
-
initialization
-
checking, 181-182
-
dynamic, 132
-
lazy, 182
-
object factories and, 197
-
static, 132
-
insert, 205
-
InsertChar, 120, 122, 125-126
-
Instance, 131-132, 135-137, 146, 151
-
instantiation, 13-14, 120, 272, 274
-
int, 159
-
Int2Type, 29-31, 68-69
-
interface(s)
-
Abstract Factory design pattern, 223-226
-
application program (APIs), 161, 306
-
do-it-all, failure of, 4-5
-
granular, 224
-
graphical user (GUI), 102
-
separation, 101
-
intrusive reference counting, 167. See also reference counting
-
IntType, 186, 304
-
InvocationTraits, 275
-
isConst, 47
-
isPointer, 47
-
isReference, 41, 47
-
isStdArith, 47
-
isStdFloat, 47
-
isStdFundamental, 42-43, 47
-
isStdIntegral, 47
-
isStdSignedInt, 47
-
isStdUnsignedInt, 47
-
isVolatile, 47
K
-
KDL problem, 135-142, 155
-
Keyboard, 135-142, 155
-
KillPhoenixSingleton, 138
-
Knuth, Donald E., 77, 78
L
-
Lattanzi, Len, 77
-
Length, 76
-
less, 180-181
-
LhsTypes, 272
-
Lifetime policy, 149-153
-
LifetimeTracker, 142-143
-
LIFO (last in, first out), 134
-
Line, 203, 204, 212-213
-
linking, reference, 167-168
-
LISP, 52
-
ListOfTypes, 295
-
Lock, 146, 184, 306
-
LockedStorage, 189-190
-
locking
-
class-level, 307
-
object-level, 306-308
-
pattern, double-checked, 146-147, 149
-
semantics, 306-308
-
LockingProxy, 184-185
-
Log, 135-142
-
logarithmic double dispatcher, 263, 276-285, 297-300
-
logic_error, 152
-
Loki, 70, 77, 91-92, 210, 303, 309
-
multimethods and, 263, 268, 277-278, 288, 295-300
-
mutexes and, 306
-
smart pointers and, 163
-
long double data type, 35
-
longevity, 139-145, 149, 151
-
lower_bound, 277
M
-
MacroCommand, 122
-
macros, 122, 251-252, 254, 256-257, 261
-
"maelstrom effect," 170
-
MAKE_VISITABLE, 261
-
MakeAdapter, 28-29
-
MakeCopy, 164
-
MakeT, 223
-
malloc, 143
-
map, 204-205, 210, 277, 278
-
mapping
-
integral constants to types, 31-32
-
type-to-type, 31-33
-
Martin, Robert, 245
-
maxObjectSize, 88
-
MAX_SMALL_OBJECT_SIZE, 93-94, 95
-
MemControlBlock, 78-79
-
MemFunHandler, 117-119, 126
-
memory
-
allocators, workings of, 78-80
-
chunks of, 81-87
-
heaps, 124-125, 189-190
-
RMW (read-modify-write) operation, 303-304
-
Meyers, Scott, 77, 133-134, 276, 280
-
Meyers singleton, 133-134
-
ML, 263
-
ModalDialog, 27
-
Monster, 219-222, 224, 229
-
More Effective C++ (Meyers), 276, 280
-
MostDerived, 63, 76
-
multimethods
-
arguments and, 285-290
-
basic description of, 263-300
-
constant-time, 290-293
-
double switch-on-type and, 265-268
-
logarithmic double dispatcher and, 276-285
-
need for, 264-265
-
quick facts, 297-300
-
symmetry and, 273-74
-
Multimethods.h, 294
-
MultiThreaded, 6
-
MultiThreadedRefCounting, 186-187
-
multithreading, 145-148, 302-306
-
at the bookkeeping data level, 185-187
-
critique of, 302-303
-
library, 301-309
-
mutexes and, 305-306
-
at the pointee object level, 184-185
-
reference counting and, 186
-
reference tracking and, 186-187
-
smart pointers and, 184-187
-
mutex_, 146
-
mutexes, 146-147, 305-306
-
MyController, 27
-
MyOnlyPrinter, 130
-
MyVisitor, 257
N
-
name, 206
-
name cyclic dependency, 243
-
new[], 183
-
next_, 187
-
NiftyContainer, 28-30, 33-34
-
NoChecking, 15, 18-19
-
NoCopy, 192
-
NoDestroy, 153
-
NoDuplicates, 60-61, 76
-
NonConstType, 47
-
nontemplated operators, 176-177
-
NonVolatileType, 47
-
NoQualifiedType, 47
-
NullType, 39-41, 48, 52, 54-56, 62-63, 270
O
-
object factor(ies)
-
basic description of, 197-218
-
classes and, 200-201
-
generalization and, 207-210
-
implementing, 201-206
-
need for, 198-200
-
quick facts, 216-217
-
templates, 216-218
-
type identifiers and, 206-207
-
using, with generic components, 215
-
ObjectLevelLockable, 307-309
-
OnDeadReference, 136-139, 150
-
OnError, 272
-
OnEvent, 70-71
-
OnUnknownVisitor, 260, 262
-
operators
-
operator.*, 104, 116-117
-
operator!=, 174, 176, 178
-
operator(), 103-113, 116, 122-127, 283, 285
-
operator2>, 157, 160-162, 165, 182-185
-
operator2>*, 104, 116-117
-
operator*, 157, 161-162, 178-179, 182
-
operator<, 144
-
operator<=, 178-179
-
operator=, 162
-
operator==, 176-177, 178
-
operator>, 178-179
-
operator>=, 178-179
-
operator[], 55, 183, 278
-
operator T*, 172
-
OpNewCreator, 10
-
OpNewFactoryUnit, 226, 227, 231, 234
-
OrderedTypeInfo, 217, 276-277
-
orthogonal policies, 20
-
OutIt, 40
-
ownership-handling strategies, 163-170
-
Ownership policy, 183-184, 186, 188, 190-192
P
-
Paragraph, 237, 241, 247, 249, 254, 256
-
ParagraphVisitor, 246, 247, 248, 251
-
parameter(s)
-
template, 10-11, 64, 105
-
types, optimized, 43-44
-
ParameterType, 43-44, 47, 123
-
ParentFunctor, 111, 120-121
-
Parm1, 111
-
Parm2, 111
-
ParmN, 109
-
Parrot, 117-119
-
pattern(s)
-
Abstract Factory pattern, 69, 49-51, 219-234
-
Command pattern, 99-104
-
Double-Checked Locking pattern, 146-147, 149
-
Prototype design pattern, 228-233
-
Strategy design pattern, 8
-
Pattern Hatching (Vlissides), 133
-
pData_, 86
-
pDocElem, 246
-
pDuplicateShape, 212
-
pDynObject, 140
-
pFactory_, 222
-
Phoenix Singleton, 137-142, 149, 153
-
pimpl idiom, 78
-
pInstance_, 131-132, 136, 138, 146-148, 151
-
placement new, 138
-
pLastAlloc_, 89
-
POD (plain old data) structure, 45-46
-
Point3D, 70
-
pointee_, 160, 161, 178, 183
-
PointeeType, 41-42, 47, 160-161
-
pointee object level, 184-185
-
pointer(s)
-
address-of operator and, 170-171
-
arrays and, 183-184
-
basic description of, 157-195
-
checking issues and, 181-182
-
copy on write (COW) and, 165
-
deep copy and, 163-164
-
destructive copy and, 168-170
-
equality and, 173-178
-
error reporting and, 181-182
-
failure of the do-it-all interface and, 5
-
handling, to member functions, 115-119
-
implicit conversion and, 171-173
-
inequality and, 173-178
-
multithreading and, 184-187
-
ordering comparison operators and, 178-181
-
ownership-handling strategies, 163-170
-
quick facts, 194-195
-
raw, 171-173
-
reference counting and, 165-167, 186
-
reference linking and, 166-168
-
reference tracking and, 186-187
-
traits of, implementing, 41-42
-
types, implicit conversion, 171-173
-
PointerToObj, 118
-
PointerTraits, 41-42
-
PointerType, 160, 190-191
-
policies. See also policy classes
-
basic description of, 3, 7-11
-
BasicDispatcher and, 293-294
-
BasicFastDispatcher and, 293-294
-
compatible, 17-18
-
decomposing classes in, 19-20
-
enriched, 12
-
multimethods and, 293-294
-
noncompatible, 17-18
-
orthogonal, 20
-
singletons and, 149-150, 152-153
-
stock, 152-153
-
policies (listed by name). See also policies
-
Array policy, 19-20
-
CastingPolicy policy, 288, 299
-
CatchAll Policy, 260, 262
-
Checking policy, 15-16, 188, 193-194
-
Conversion policy, 36-37, 188, 192-193
-
Creation policy, 151, 153
-
Creator policy, 8-9, 11-14, 149, 155, 156
-
Destroy policy, 20
-
DispatcherBackend policy, 294
-
FactoryError policy, 208-209, 217-218, 234
-
Lifetime policy, 149-153
-
Ownership policy, 183-184, 186, 188, 190-192
-
Storage policy, 17, 185, 188, 189-190
-
Structure policy, 16-17
-
ThreadingModel policy, 16, 149, 151-153, 186, 303-309
-
policy classes. See also classes
-
basic description of, 3-22
-
combining, 14-16
-
customizing structure with, 16-17
-
destructors of, 12-13
-
implementing, 10-11
-
Poly, 271, 279
-
Polygon, 203, 212
-
polymorphism, 78, 163-164
-
Abstract Factory implementation and, 228-229
-
multimethods and, 264
-
object factories and, 197-200, 211-212
-
prev_, 187
-
Printer, 161-162
-
printf, 105
-
printingPort_, 130
-
priority_queue, 142-145
-
ProductCreator, 210-211, 216-217
-
Prototype design pattern, 228-233
-
PrototypeFactoryUnit, 231-232, 234
-
prototypes, 228-233
-
pTrackerArray, 143
Q
-
qualifiers, stripping, 44
R
-
RasterBitmap, 237, 241, 247, 249, 256
-
RasterBitmapVisitor, 247, 251
-
realloc, 143
-
Receiver, 100
-
Rectangle, 267, 279, 289
-
RectanglePoly, 279
-
Redo, 125-126
-
RefCounted, 6, 192
-
RefCountedMT, 192
-
reference(s)
-
counting, 165-167, 186
-
linking, 167-168, 186-187
-
ReferencedType, 41-42, 47
-
RefLinked, 192
-
RegisterShape, 206
-
RejectNull, 194
-
RejectNullStatic, 193-194
-
RejectNullStrict, 194
-
Release, 161-162, 192, 305, 306
-
Replace, 76
-
ReplaceAll, 61, 76
-
Reset, 162
-
resource leaks, 133
-
Result, 55
-
ResultType, 111, 269, 284
-
return type(s)
-
conversion, 114-115
-
covariant, 228
-
generalized functors and, 114-115
-
RISC processors, 148
-
RMW (read-modify-write) operation, 303-304
-
RoundedRectangle, 272, 286-287, 289
-
RoundedShape, 286-287, 289
-
runtime_error, 137, 209-210, 300
-
runtime type information (RTTI), 215, 245, 255, 276
S
-
safe_reinterpret_cast, 26
-
SafeWidgetPtr, 17
-
sameType, 36
-
Save, 201-203
-
scanf, 105
-
ScheduleDestruction, 149-150
-
Schmidt, Douglas, 146-147
-
Scroll, 122
-
ScrollBar, 50, 61-62
-
Secretary, 5
-
Section, 254
-
Select, 33-34, 62
-
semantics
-
failure of the do-it-all interface and, 4-5
-
functors and, 99
-
locking, 306-308
-
semaphores, 309
-
SetLongevity, 140-145, 149
-
SetPrototype, 12, 14, 232
-
Shape, 201-202, 265, 268, 279, 286-289
-
ShapeCast, 289
-
ShapeFactory, 204-205, 215
-
Shapes, 290
-
SillyMonster, 219-222, 226
-
SillySoldier, 219-222, 230
-
SillySuperMonster, 219-222
-
SingleThreaded, 153, 308
-
singleton(s). See also SingletonHolder
-
basic C++ idioms supporting, 131-132
-
dead reference problem and, 135-142
-
destroying, 133-135
-
Double-Checked Locking pattern and, 146-147
-
failure of the do-it-all interface and, 4-5
-
implementing, 129-154
-
longevity and, 139-145
-
Meyers singleton, 133-134
-
multithreading and, 145-148
-
Phoenix, 137-142, 149, 153
-
static functions and, 130
-
uniqueness of, enforcing, 132-133
-
SingletonHolder, 3, 91, 129-130, 148-153, 215. See also singletons
-
assembling, 150-152
-
decomposing, 149-150
-
quick facts, 155-156
-
working with, 153-156
-
SingletonWithLongevity, 153, 154
-
sizeof, 25, 34-35, 82, 90-91
-
size_t, 36, 79
-
skinnable programs, 103
-
SmallAlloc.h, 93-95
-
small-object allocation
-
basic description of, 77-96
-
default free store allocators and, 78
-
fixed-size allocators and, 84-87
-
hat trick and, 89-91
-
memory chunks and, 81-84
-
quick facts, 94-95
-
SmallObjAllocator, 80-81, 87-89, 92-95
-
SmallObject, 80-81, 89, 91-95, 123-124
-
smart pointer(s)
-
address-of operator and, 170-171
-
arrays and, 183-184
-
basic description of, 157-195
-
checking issues and, 181-182
-
copy on write (COW) and, 165
-
deep copy and, 163-164
-
destructive copy and, 168-170
-
equality and, 173-178
-
error reporting and, 181-182
-
failure of the do-it-all interface and, 5
-
implicit conversion and, 171-173
-
inequality and, 173-178
-
multithreading and, 184-187
-
ordering comparison operators and, 178-181
-
ownership-handling strategies, 163-170
-
quick facts, 194-195
-
raw, 171-173
-
reference counting and, 165-167, 186
-
reference linking and, 167-168
-
reference tracking and, 186-187
-
types, implicit conversion, 171-173
-
SmartPtr, 3, 6-7, 14-19, 44, 87, 157-195
-
Soldier, 219-222, 224, 229-230
-
SomeLhs, 278, 284
-
SomeRhs, 278, 284
-
SomeThreadingModel, 309
-
SomeVisitor, 250, 254
-
spImpl_, 112
-
statements
-
if, 238, 267, 305
-
if-else, 29, 267, 268, 270
-
static, 280
-
static_cast, 114, 285-290, 299
-
STATIC_CHECK, 25
-
StaticDispatcher, 268-276, 297-298
-
static manipulation, 6
-
Statistics, 249
-
stats, 246-247
-
STL, 115, 171
-
StorageImpl, 189, 190
-
Storage policy, 17, 185, 188, 189-190
-
Strategy design pattern, 8
-
String, 302-303, 307
-
Stroustrup, Bjarne, 202
-
struct, 45
-
structure(s)
-
customizing, with policy classes, 16-17
-
POD (plain old data), 45-46
-
specialization of, 7
-
Structure policy, 16-17
-
SuperMonster, 219-222, 229
-
SUPERSUBCLASS, 37, 62
-
Surprises.cpp, 224
-
Sutter, Herb, 77
-
switch, 203
-
SwitchPrototype, 13-14
-
symmetry, 273-74
-
synchronization objects, 303
T
-
template(s)
-
advantages of, 6-7
-
implementing policy classes with, 11
-
skeleton, Functor class, 104-108
-
specialization, partial, 53-54
-
template parameters, 10-11, 64, 105
-
templated operators, 176-177
-
TemporarySecretary, 5
-
Tester, 178
-
Tester*, 178
-
TestFunction, 113-115
-
TextDocument, 198
-
ThreadingModel policy, 16, 149, 151-153, 186, 303-309
-
time
-
separation, 101
-
slicing, 201
-
TList, 53-65, 75, 120, 127, 223, 231-234, 261
-
Tools menu, 102
-
trampoline functions (thunks), 280-283
-
Trampoline, 281
-
translation units, 132
-
Triangle, 289
-
tuples, generating, 70
-
type(s)
-
atomic operations on, 303-304
-
conversions, generalized functors and, 114-115
-
detection of fundamental, 42-43
-
identifiers, 201, 206-207
-
integral, 303-305
-
modifiers, 308-309
-
multiple inheritance and, 6
-
multithreading and, 303-305
-
parameters, optimized, 43-44
-
replacing an element in, 60-61
-
safety, loss of static, 4
-
selection, 33-34
-
-to-type mapping, 31-33
-
traits, 38-46
-
Type2Type, 32-33, 223
-
TypeAt, 55, 76
-
TypeAtNonStrict, 55, 76, 109
-
typedef, 14, 19, 51, 54, 215, 295
-
typeid, 38, 267
-
type_info, 37-39, 54, 206-207, 213-215, 276-277, 295
-
TypeInfo, 38-39, 48
-
TYPELIST, 295
-
Typelist.h, 51, 55, 75
-
typelists, 223, 268, 272
-
appending to, 57-58
-
basic description of, 49-76
-
calculating length and, 53-54
-
class generation with, 64-75
-
compile-time algorithms operating on, 76
-
creating, 52-53
-
defining, 51-52
-
detecting fundamental types and, 42-43
-
need for, 49-41
-
partially ordering, 61-64
-
quick facts, 75
-
searching, 56-57
-
TypesLhs, 269-270, 274
-
TypesRhs, 269, 270, 274
-
TypeTraits, 41-48, 123, 183
U
-
UCHAR_MAX, 83
-
Undo, 125-126
-
unique bouncing virtual functions, 238
-
Unlock, 184
-
UpdateStats, 237-238
-
upper_bound, 144
-
use_Size, 91
V
-
ValueType, 33
-
vector, 183
-
VectorGraphic, 244
-
VectorizedDrawing, 259
-
Veldhuizen, Todd, 54
-
virtual
-
constructor dilemma, 229
-
functions, 238
-
Visit, 249-250, 254, 256
-
Visitable, 249, 251, 252-254
-
Visitor design pattern
-
acyclic, 243-248
-
basic description of, 235-262
-
catch-all function and, 242-243, 258-259
-
cyclic, 243-248, 254-257
-
generic implementation of, 248-255
-
hooking variations, 258-260
-
nonstrict visitation and, 261
-
quick facts, 261-262
-
VisitParagraph, 240, 242
-
VisitRasterBitmap, 242
-
VisitVectorGraphic, 244
-
Vlissides, John, 133
-
void*, 172
-
volatile, 151, 308-309, 308-309
-
VolatileType, 151, 309
W
-
Widget, 26-32, 38, 44, 61-62, 159, 164, 184, 309
-
WidgetEventHandler, 71-74
-
WidgetFactory, 49-51
-
WidgetInfo, 65-67
-
WidgetManager, 9-14, 19-20
-
Window, 50
-
Withdrawal, 306
X
-
X Windows, 103