在本书中,Andrei Alexandrescu为读者展示了一种C++设计的新思维。在展现其非凡的创造力和精湛的编程技术的同时,Alexandrescu提出了一种融合了设计模式、泛型编程、C++等尖端设计技术的方法,以帮助程序员编写清晰、灵活、高度可重用的代码。\r\n 本书提出了泛型组件(generic component)的概念,这是一种可重用的设计模板,可用来产生规范的C++代码。泛型组件还提供了从设计到代码的无缝转换,生成更能表达设计者最初意图的代码,并支持设计模式的重用——只需改动少量的代码。
Foreword by Scott Meyers\r\nForeword by John Vlissides\r\nPreface\r\nAcknowledgments\r\n\r\nPart I Techniques\r\n\r\nChapter 1 Policy-Based Class Design\r\n\r\n1.1 The Multiplicity of Software Design\r\n1.2 The Failure of the Do-It-All Interface\r\n1.3 Multiple Inheritance to the Rescue?\r\n1.4 The Benefit of Templates\r\n1.5 Policies and Policy Classes\r\n1.6 Enriched Policies\r\n1.7 Destructors of Policy Classes\r\n1.8 Optional functionality Through Incomplete Instantiation\r\n1.9 Combining Policy Classes\r\n1.10 Customizing Structure with Policy Classes\r\n1.11 Compatible and Incompatible Policies\r\n1.12 Decomposing a Class into Policies\r\n1.13 Summary\r\n\r\nChapter 2 Techniques\r\n\r\n2.1 Compile-Time Assertions\r\n2.2 Partial Template Specialization\r\n2.3 Local Classes\r\n2.4 Mapping Integral Constants to Types\r\n2.5 Type-to-Type Mapping\r\n2.6 Type Selection\r\n2.7 Detecting Convertibility and Inheritance at Compile Time\r\n2.8 A Wraper Around type_info\r\n2.9 NullType and EmptyType\r\n2.10 Type Traits\r\n2.11 Summary\r\n\r\nChapter 3 Typelists\r\n\r\n3.1 The Need for Typelists\r\n3.2 Defining Typelists\r\n3.3 Linearizing Typelist Creation\r\n3.4 Calculating Length\r\n3.5 Intermezzo\r\n3.6 Indexed Access\r\n3.7 Searching Typelists\r\n3.8 Appending to Typelists\r\n3.9 Erasing a Type from a Typelist\r\n3.10 Erasing duplicates\r\n3.11 Replacing an Element in a Typelist\r\n3.12 Partially Ordering Typelists\r\n3.13 Class Generation with Typelists\r\n3.14 Summary\r\n3.15 Typelist Quick Facts\r\n\r\nChapter 4 Small-Object Allocation\r\n\r\n4.1 The Default Free Store Allocator\r\n4.2 The Workings of a Memory Allocator\r\n4.3 A Small-Object Allocator\r\n4.4 Chunks\r\n4.5 The Fixed-Size Allocator\r\n4.6 The SmallObjAllocator Class\r\n4.7 A Hat Trick\r\n4.8 Simple,Complicated,Yet Simple in the End\r\n4.9 Administrivia\r\n4.10 Summary\r\n4.11 Small-Object Allocator Quick Facts\r\n\r\nPart II Components\r\n\r\nChapter 5 Generalized Functors\r\n\r\n5.1 The Command Design Pattern\r\n5.2 Command in the Real Worls\r\n5.3 C++Callable Entities\r\n5.4 The Functor Class Template Skeleton\r\n5.5 Implementing the Forwarding Functor::operator()\r\n5.6 Handling Functors\r\n5.7 Build One,Get One Free\r\n5.8 Argument and Return Type Conversions\r\n5.9 Handling Pointers to Member Functions\r\n5.10 Binding\r\n5.11 Chaining Requests\r\n5.12 Real-World Issues I:The Cost of Forwarding Functions\r\n5.13 Real-World Issues II:Heap Allocation\r\n5.14 Implementing Undo and Redo with Functor\r\n5.15 Summary\r\n5.16 Functor Quick Facts\r\n\r\nChapter 6 Implementing Singletons\r\n\r\n6.1 Static Data+Static Functions!=singleton\r\n6.2 The Basic C++Idioms Supporting Singleton\r\n6.3 Enforcing the Singleton's Uniqueness\r\n6.4 Destroying the Singleton\r\n6.5 The Dead Reference Problem\r\n6.6 Addressing the Dead Reference Problem(I):The Phoenix Singleton\r\n6.7 Addressing the Dead Reference Problem(II):Singletons with Longevity\r\n6.8 Implementing Singletons with Longevity\r\n6.9 Living in a Multithreaded World\r\n6.10 Putting It All Together\r\n6.11 Working with singletonHolder\r\n6.12 Summary\r\n6.13 SingletonHolder Class Template Quick Facts\r\n\r\nChapter 7 Smart Pointers\r\n\r\n7.1 Smart Pointers 101\r\n7.2 The Deal\r\n7.3 Storage of Smart Pointers\r\n7.4 Smart Pointer Member Functions\r\n7.5 Ownership-Handling Strategies\r\n7.6 The Address-of Operator\r\n7.7 Implicit Conversion to Raw Pointer Types\r\n7.8 Equality and Inequality\r\n7.9 Ordering Comparisons\r\n7.10 Checking and Error Reporting\r\n7.11 Smart Pointers to const and const Smart Pointers\r\n7.12 Arrays\r\n7.13 Smart Pointers and Multithreading\r\n7.14 Putting It All Together\r\n7.15 Summary\r\n7.16 SmartPtr Quick Facts\r\n\r\nChapter 8 Object Factories\r\n\r\n8.1 The Need for Object Factories\r\n8.2 Object Factories in C++:Classes and Objects\r\n8.3 Implementing an Object Factory\r\n8.4 Type Identifiers\r\n8.5 Generalization\r\n8.6 Minutiae\r\n8.7 Clone Factories\r\n8.8 Using Object Factories with Other Generic Components\r\n8.9 Summary\r\n8.10 Factory Class Template Quick Facts\r\n8.11 CloneFactory Class Template Quick Facts\r\n\r\nChapter 9 Abstract Factory\r\n\r\n9.1 The Architectural Role of Abstract Factory\r\n9.2 A Generic Abstract Factory Interface\r\n9.3 Implementing AbstractFactory\r\n9.4 A Prototype-Based Abstract Factory Implementation\r\n9.5 Summary\r\n9.6 AbstractFactory and ConcreteFactory Quick Facts\r\n\r\nChapter 10 Visitor\r\n\r\n10.1 Visitor Basics\r\n10.2 Overloading and the Catch-All Function\r\n10.3 An Implementation Refinement:The Acyclic Visitor\r\n10.4 A Generic Implementation of Visitor\r\n10.5 Back to the “Cyclic”Visitor\r\n10.6 Hooking Variations\r\n10.7 Summary\r\n10.8 Visitor Generic Component Quick Facts\r\n\r\nChapter 11 Multimethods\r\n\r\n11.1 What Are Multimethods?\r\n11.2 When Are Multimethods Needed?\r\n11.3 Double Switch-on-Type:Brute Force\r\n11.4 The Brute-Force Approach Automated\r\n11.5 Symmetry with the Brute-Force Dispatcher\r\n11.6 The Logarithmic Double Dispatcher\r\n11.7 FnDispatcher and Symmetry\r\n11.8 Double Dispatch to Functors\r\n11.9 Converting Arguments:static_cast or dynamic_cast?\r\n11.10 Constant-Time Multimethods:Raw Speed\r\n11.11 BasicDispatcher and BasicFastDispatcher as Policies\r\n11.12 Looking Forward\r\n11.13 Summary\r\n11.14 Double Dispatcher Quick Facts\r\n\r\nAppendix A Minimalist Multithreading Library\r\n\r\nA.1 A Critique of Multithreading\r\nA.2 Loki's Approach\r\nA.3 Atomic Operations on Integral Types\r\nA.4 Mutexes\r\nA.5 Locking Semantics in Object-Oriented Programming\r\nA.6 Optional volatile Modifier\r\nA.7 Semaphores,Events,and Other Good Things\r\nA.8 Summary\r\n\r\nBibliography\r\nIndex
You might be holding this book in a bookstore, asking yourself whether you should buy it. Or maybe you are in your employer's library, wondering whether you should invest time in reading it. I know you don't have time, so I'll 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 don't 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; it's int. You change one line of code. The smart pointers to Wi dget 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 have changed the design. Compile. Link. Done.
Well, there is something wrong with this scenario, isn't 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.., that's the way a programmer's 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 has 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 manyancillary 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 combinatorial--and essentially open-ended--number 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 design--recipes for sound, reusable solutions to problems that can be encountered in many contexts. 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 isa 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 ali 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 the 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 techniques used, errors in mixing and matching the appropriate pieces are usually caught during compile time.
This book's manifest intent is to create generic components--preimplemented 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 complementary--whereas 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.