Professional C++ 0764574841, 2004027959, 1941951961, 9780764574849

Geared to experienced C++ developers who may not be familiar with the more advanced features of the language, and theref

1,114 86 3MB

English Pages 838 [866] Year 2005

Report DMCA / Copyright

DOWNLOAD FILE

Polecaj historie

Professional C++
 0764574841, 2004027959, 1941951961, 9780764574849

Table of contents :
Professional C++......Page 3
Acknowledgments......Page 5
Author Bios......Page 6
Contents......Page 7
What This Book Covers......Page 23
How This Book Is Structured......Page 24
Conventions......Page 25
p2p. wrox. com......Page 26
The Basics of C++......Page 29
Diving Deeper into C++......Page 46
C++ as an Object-Oriented Language......Page 54
Your First Useful C++ Program......Page 57
Summary......Page 69
Chapter 2: Designing Professional C++ Programs......Page 71
The Importance of Programming Design......Page 72
What’s Different about C++ Design?......Page 74
Two Rules for C++ Design......Page 75
Designing a Chess Program......Page 78
Summary......Page 84
An Object-Oriented View of the World......Page 85
Summary......Page 104
Reusing Code......Page 105
Designing with Patterns and Techniques......Page 129
Summary......Page 131
Chapter 5: Designing for Reuse......Page 133
How to Design Reusable Code......Page 134
Summary......Page 146
The Need for Process......Page 147
Software Life-Cycle Models......Page 148
Software-Engineering Methodologies......Page 155
Building Your Own Process and Methodology......Page 160
Summary......Page 161
The Importance of Looking Good......Page 163
Documenting Your Code......Page 164
Decomposition......Page 173
Naming......Page 176
Using Language Features with Style......Page 179
Formatting......Page 180
Summary......Page 183
Introducing the Spreadsheet Example......Page 185
Writing Classes......Page 186
Object Life Cycles......Page 193
Summary......Page 210
Dynamic Memory Allocation in Objects......Page 211
Different Kinds of Data Members......Page 222
More about Methods......Page 227
Nested Classes......Page 234
Friends......Page 236
Operator Overloading......Page 237
Pointers to Methods and Members......Page 245
Building Abstract Classes......Page 246
Summary......Page 249
Chapter 10: Discovering Inheritance Techniques......Page 251
Building Classes with Inheritance......Page 252
Inheritance for Reuse......Page 258
Respect Your Parents......Page 262
Inheritance for Polymorphism......Page 268
Multiple Inheritance......Page 276
Interesting and Obscure Inheritance Issues......Page 281
Summary......Page 298
Chapter 11: Writing Generic Code with Templates......Page 299
Overview of Templates......Page 300
Class Templates......Page 301
Function Templates......Page 323
Advanced Templates......Page 327
Summary......Page 350
References......Page 351
Keyword Confusion......Page 358
Types and Casts......Page 365
Header Files......Page 371
C Utilities......Page 373
Summary......Page 376
Working with Dynamic Memory......Page 377
Array-Pointer Duality......Page 390
Dynamic Strings......Page 393
Low-Level Memory Operations......Page 397
Common Memory Pitfalls......Page 402
Summary......Page 406
Using Streams......Page 407
String Streams......Page 418
File Streams......Page 420
Bidirectional I/O......Page 424
Internationalization......Page 425
Summary......Page 428
Chapter 15: Handling Errors......Page 429
Errors and Exceptions......Page 430
Exception Mechanics......Page 432
Exceptions and Polymorphism......Page 444
Stack Unwinding and Cleanup......Page 450
Common Error-Handling Issues......Page 452
Putting It All Together......Page 456
Summary......Page 458
Chapter 16: Overloading C++ Operators......Page 459
Overview of Operator Overloading......Page 460
Overloading the Arithmetic Operators......Page 466
Overloading the Insertion and Extraction Operators......Page 469
Overloading the Subscripting Operator......Page 471
Overloading the Function Call Operator......Page 476
Overloading the Dereferencing Operators......Page 477
Writing Conversion Operators......Page 481
Overloading the Memory Allocation and Deallocation Operators......Page 485
Summary......Page 491
Overview of Performance and Efficiency......Page 493
Language-Level Efficiency......Page 495
Design-Level Efficiency......Page 500
Profiling......Page 507
Summary......Page 516
Cross-Platform Development......Page 517
Cross-Language Development......Page 522
Summary......Page 533
Quality Control......Page 535
Unit Testing......Page 538
Higher-Level Testing......Page 551
Summary......Page 554
The Fundamental Law of Debugging......Page 555
Planning for Bugs......Page 556
Debugging Techniques......Page 569
Summary......Page 587
Chapter 21: Delving into the STL: Containers and Iterators......Page 589
Containers Overview......Page 590
Sequential Containers......Page 593
Container Adapters......Page 616
Associative Containers......Page 623
Other Containers......Page 639
Summary......Page 646
Chapter 22: Mastering STL Algorithms and Function Objects......Page 647
Overview of Algorithms......Page 648
Function Objects......Page 652
Algorithm Details......Page 659
Algorithms and Function Objects Example: Auditing Voter Registrations......Page 676
Summary......Page 681
Chapter 23: Customizing and Extending the STL......Page 683
Iterator Adapters......Page 684
Extending the STL......Page 688
Summary......Page 719
The Appeal of Distributed Computing......Page 721
Distributed Objects......Page 724
CORBA......Page 730
XML......Page 737
Summary......Page 756
Chapter 25: Incorporating Techniques and Frameworks......Page 757
“I Can Never Remember How to . . .”......Page 758
There Must Be a Better Way......Page 764
Object-Oriented Frameworks......Page 778
Summary......Page 780
Chapter 26: Applying Design Patterns......Page 781
The Singleton Pattern......Page 782
The Factory Pattern......Page 788
The Proxy Pattern......Page 794
The Adapter Pattern......Page 796
The Decorator Pattern......Page 801
The Chain of Responsibility Pattern......Page 804
The Observer Pattern......Page 806
Summary......Page 809
Chapter 1: A Crash Course in C++......Page 811
Chapter 2: Designing Professional C++ Programs......Page 812
Chapter 3: Designing with Objects......Page 813
Chapter 4: Designing with Libraries and Patterns......Page 814
Chapter 6: Maximizing Software Engineering Methods......Page 815
Chapter 7: Coding with Style......Page 816
Chapters 8 and 9: Classes and Objects......Page 817
Chapter 10: Discovering Inheritance Techniques......Page 820
Chapter 12: Understanding C++ Quirks and Oddities......Page 821
Chapter 13: Effective Memory Management......Page 822
Chapter 14: Demystifying C++ I/O......Page 823
Chapter 16: Overloading C++ Operators......Page 824
Chapter 17: Writing Efficient C++......Page 825
Chapter 19: Becoming Adept at Testing......Page 826
Chapters 21, 22, and 23: The Standard Template Library......Page 827
Chapter 24: Exploring Distributed Objects......Page 828
Chapter 26: Applying Design Patterns......Page 829
Appendix B: Annotated Bibliography......Page 831
Index......Page 841

Citation preview

Professional C++ Nicholas A. Solter Scott J. Kleper

Professional C++ Nicholas A. Solter Scott J. Kleper

Professional C++ Published by Wiley Publishing, Inc. 10475 Crosspoint Boulevard Indianapolis, IN 46256

www.wiley.com Copyright © 2005 by Wiley Publishing, Inc. All rights reserved. Published simultaneously in Canada Printed in the United States of America 10 9 8 7 6 5 4 3 2 1 1B/QV/QR/QV/IN No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, scanning or otherwise, except as permitted under Sections 107 or 108 of the 1976 United States Copyright Act, without either the prior written permission of the Publisher, or authorization through payment of the appropriate per-copy fee to the Copyright Clearance Center, 222 Rosewood Drive, Danvers, MA 01923, (978) 750-8400, fax (978) 646-8600. Requests to the Publisher for permission should be addressed to the Legal Department, Wiley Publishing, Inc., 10475 Crosspoint Blvd., Indianapolis, IN 46256, (317) 572-3447, fax (317) 572-4355, e-mail: [email protected]. LIMIT OF LIABILITY/DISCLAIMER OF WARRANTY: THE PUBLISHER AND THE AUTHOR MAKE NO REPRESENTATIONS OR WARRANTIES WITH RESPECT TO THE ACCURACY OR COMPLETENESS OF THE CONTENTS OF THIS WORK AND SPECIFICALLY DISCLAIM ALL WARRANTIES, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE. NO WARRANTY MAY BE CREATED OR EXTENDED BY SALES OR PROMOTIONAL MATERIALS. THE ADVICE AND STRATEGIES CONTAINED HEREIN MAY NOT BE SUITABLE FOR EVERY SITUATION. THIS WORK IS SOLD WITH THE UNDERSTANDING THAT THE PUBLISHER IS NOT ENGAGED IN RENDERING LEGAL, ACCOUNTING, OR OTHER PROFESSIONAL SERVICES. IF PROFESSIONAL ASSISTANCE IS REQUIRED, THE SERVICES OF A COMPETENT PROFESSIONAL PERSON SHOULD BE SOUGHT. NEITHER THE PUBLISHER NOT THE AUTHOR SHALL BE LIABLE FOR DAMAGES ARISING HEREFROM. THE FACT THAT AN ORGANIZATION OR WEB SITE IS REFERRED TO IN THIS WORK AS A CITATION AND/OR A POTENTIAL SOURCE OF FURTHER INFORMATION DOES NOT MEAN THAT THE AUTHOR OR THE PUBLISHER ENDORSES THE INFORMATION THE ORGANIZATION OR WEB SITE MAY PROVIDE OR RECOMMENDATIONS IT MAY MAKE. FURTHER, READERS SHOULD BE AWARE THAT INTERNET WEBSITES LISTED IN THIS WORK MAY HAVE CHANGED OR DISAPPEARED BETWEEN WHEN THIS WORK WAS WRITTEN AND WHEN IT IS READ. For general information on our other products and services please contact our Customer Care Department within the United States at (800) 762-2974, outside the United States at (317) 572-3993 or fax (317) 572-4002. Trademarks: Wiley, the Wiley Publishing logo, Wrox, the Wrox logo, Programmer to Programmer and related trade dress are trademarks or registered trademarks of John Wiley & Sons, Inc. and/or its affiliates. All other trademarks are the property of their respective owners. Wiley Publishing, Inc., is not associated with any product or vendor mentioned in this book. Wiley also publishes its books in a variety of electronic formats. Some content that appears in print may not be available in electronic books. Solter, Nicholas, 1977Professional C++ / Nicholas Solter, Scott Kleper. p. cm. Includes index. ISBN 0-7645-7484-1 (paper/website) 1. C++ (Computer program language) I. Kleper, Scott, 1977- II. Title. QA76.73.C153S665 2005 005.13'3--dc22 2004027959

Dedications To Sonja, for her unconditional love and support, and to my son Kai, whose frequent interruptions reminded me what’s important in life. —Nicholas A. Solter To Marni, whose unpredictable cuteness brightens every day. —Scott J. Kleper

Acknowledgments We owe a debt of gratitude to the many people who have made this book possible. We’d like to thank David Fugate of Waterside Productions for all of his advice and guidance, and Robert Elliot at Wiley for giving two unknown authors the opportunity to tell the C++ story in a new way. This book would not have turned out nearly as well as it did without the assistance of our development editor, Adaobi Obi Tulton. Thanks also to Kathryn Malm Bourgoine for her editorial assistance. The photo on the cover, which artfully minimized our nerdiness, was taken by Adam Tow. We also want to thank all of the coworkers and teachers who have encouraged us to code the right way over the years. In particular, thanks to Mike Hanson, Maggie Johnson, Adam Nash, Nick Parlante, Bob Plummer, Eric Roberts, Mehran Sahami, Bill Walker, Dan Walkowski, Patrick Young, and Julie Zelenski. Our eternal thanks to Jerry Cain, who not only taught us C++ originally, but also served as technical editor, religiously analyzing the code in this book as though it were one of our final exams. Thanks also to the following people, who reviewed one or more chapters: Rob Baesman, Aaron Bradley, Elaine Cheung, Marni Kleper, Toli Kuznets, Akshay Rangnekar, Eltefaat Shokri, Aletha Solter, Ken Solter, and Sonja Solter. Any remaining errors are, of course, our own. We’d like to thank our families for their patience and support. Finally, we’d like to thank you, our readers, for trying out our approach to professional C++ development.

Author Bios Nicholas A. Solter studied computer science at Stanford University, where he earned bachelor of science and master of science degrees, with a concentration in systems. While a student, he worked as a teaching assistant for several classes ranging from introductory computer science for nonmajors to an upperdivision course on group projects and software engineering. Now a software engineer at Sun Microsystems, Nick programs primarily in C and C++ in his work on high-availability software. His previous work experience includes several stints in the computer game industry. At Digital Media International, he was the lead programmer on the multimedia educational game, The Land Before Time Math Adventure. During an internship at Electronic Arts, he helped develop the Course Architect 2000 golf course–editing tool for the Tiger Woods PGA Tour 2000 game. In addition to his industry experience, Nick taught C++ for one year as an adjunct professor of computer science at Fullerton College. When not working, Nick enjoys reading, playing basketball, taking care of his son Kai, and spending time with his family. Scott J. Kleper began his programming career in elementary school, writing adventure games in BASIC for the Tandy TRS-80. As the resident Mac geek at his high school, Scott moved to higher-level languages and released several award-winning shareware applications. Scott attended Stanford University, where he obtained bachelor of science and master of science degrees in computer science, with a concentration in human-computer interaction. While in college, Scott served as a teaching assistant for classes involving introductory programming, object-oriented design, data structures, GUI frameworks, group projects, and Internet programming. Since graduating, Scott has served as a lead engineer on the founding teams of several companies and is currently a senior software engineer at Reactivity, Inc. Outside of work, Scott is a compulsive online shopper, an avid reader, and an awful guitarist.

Credits Vice President and Executive Group Publisher

Senior Development Editor

Richard Swadley

Adaobi Obi Tulton

Vice President and Publisher

Production Editor

Joseph B. Wikert

Felicia Robinson

Executive Editor

Media Development Specialist

Robert Elliott

Richard Graves

Editorial Manager

Technical Editor

Kathryn Malm Bourgoine

Jerry Cain

Senior Production Editor

Text Design & Composition

Geraldine Fahey

Wiley Composition Services

Cover Photographer Adam Tow

Contents Introduction Who This Book Is For What This Book Covers How This Book Is Structured What You Need to Use This Book Conventions Source Code Errata p2p.wrox.com

xxi xxi xxi xxii xxiii xxiii xxiv xxiv xxiv

Part I: Introduction to Professional C++ Chapter 1: A Crash Course in C++ The Basics of C++ The Obligatory Hello, World Namespaces Variables Operators Types Conditionals Loops Arrays Functions Those Are the Basics

Diving Deeper into C++ Pointers and Dynamic Memory Strings in C++ References Exceptions The Many Uses of const

C++ as an Object-Oriented Language Declaring a Class

1 1 2 4 6 8 10 12 14 15 16 17

18 18 21 23 23 25

26 26

Your First Useful C++ Program

29

An Employee Records System The Employee Class

29 29

Contents The Database Class The User Interface Evaluating the Program

Summary

Chapter 2: Designing Professional C++ Programs What Is Programming Design? The Importance of Programming Design What’s Different about C++ Design? Two Rules for C++ Design Abstraction Reuse

Designing a Chess Program Requirements Design Steps

Summary

Chapter 3: Designing with Objects An Object-Oriented View of the World Am I Thinking Procedurally? The Object-Oriented Philosophy Living in a World of Objects Object Relationships Abstraction

Summary

Chapter 4: Designing with Libraries and Patterns Reusing Code A Note on Terminology Deciding Whether or Not to Reuse Code Strategies for Reusing Code Bundling Third-Party Applications Open-Source Libraries The C++ Standard Library

Designing with Patterns and Techniques Design Techniques Design Patterns

Summary

vi

34 38 41

41

43 44 44 46 47 47 49

50 51 51

56

57 57 57 58 61 63 73

76

77 77 78 78 81 85 86 87

101 101 102

103

Contents Chapter 5: Designing for Reuse

105

The Reuse Philosophy How to Design Reusable Code

106 106

Use Abstraction Structure Your Code for Optimal Reuse Design Usable Interfaces Reconciling Generality and Ease of Use

Summary

Chapter 6: Maximizing Software-Engineering Methods The Need for Process Software Life-Cycle Models

107 108 112 117

118

119 119 120

The Stagewise and Waterfall Models The Spiral Method The Rational Unified Process

121 123 126

Software-Engineering Methodologies

127

Extreme Programming (XP) Software Triage

Building Your Own Process and Methodology Be Open to New Ideas Bring New Ideas to the Table Recognize What Works and What Doesn’t Work Don’t Be a Renegade

Summary

128 132

132 132 132 133 133

133

Part II: C++ Coding the Professional Way Chapter 7: Coding with Style The Importance of Looking Good Thinking Ahead Keeping It Clear Elements of Good Style

Documenting Your Code Reasons to Write Comments Commenting Styles Comments in This Book

135 135 135 136 136

136 136 140 145

vii

Contents Decomposition Decomposition through Refactoring Decomposition by Design Decomposition in This Book

Naming Choosing a Good Name Naming Conventions

145 147 147 148

148 148 148

Using Language Features with Style

151

Use Constants Take Advantage of const Variables Use References Instead of Pointers Use Custom Exceptions

151 151 151 152

Formatting The Curly Brace Alignment Debate Coming to Blows over Spaces and Parentheses Spaces and Tabs

Stylistic Challenges Summary

Chapter 8: Gaining Proficiency with Classes and Objects Introducing the Spreadsheet Example Writing Classes

152 153 154 154

155 155

157 157 158

Class Definitions Defining Methods Using Objects

158 161 164

Object Life Cycles

165

Object Creation Object Destruction Assigning to Objects Distinguishing Copying from Assignment

Summary

Chapter 9: Mastering Classes and Objects Dynamic Memory Allocation in Objects

165 176 177 180

182

183 183

The Spreadsheet Class Freeing Memory with Destructors Handling Copying and Assignment

184 186 186

Different Kinds of Data Members

194

Static Data Members Const Data Members Reference Data Members Const Reference Data Members

195 196 198 199

viii

Contents More about Methods Static Methods Const Methods Method Overloading Default Parameters Inline Methods

Nested Classes Friends Operator Overloading Implementing Addition Overloading Arithmetic Operators Overloading Comparison Operators Building Types with Operator Overloading

Pointers to Methods and Members Building Abstract Classes Using Interface and Implementation Classes

Summary

Chapter 10: Discovering Inheritance Techniques Building Classes with Inheritance

199 199 200 202 203 204

206 208 209 209 212 215 216

217 218 218

221

223 224

Extending Classes Overriding Methods

224 227

Inheritance for Reuse

230

The WeatherPrediction Class Adding Functionality in a Subclass Replacing Functionality in a Subclass

Respect Your Parents Parent Constructors Parent Destructors Referring to Parent Data Casting Up and Down

Inheritance for Polymorphism Return of the Spreadsheet Designing the Polymorphic Spreadsheet Cell The Spreadsheet Cell Base Class The Individual Subclasses Leveraging Polymorphism Future Considerations

Multiple Inheritance Inheriting from Multiple Classes Naming Collisions and Ambiguous Base Classes

230 231 233

234 234 235 237 239

240 240 241 242 243 245 246

248 248 249

ix

Contents Interesting and Obscure Inheritance Issues Changing the Overridden Method’s Characteristics Special Cases in Overriding Methods Copy Constructors and the Equals Operator The Truth about Virtual Runtime Type Facilities Non-Public Inheritance Virtual Base Classes

Summary

Chapter 11: Writing Generic Code with Templates Overview of Templates Class Templates Writing a Class Template How the Compiler Processes Templates Distributing Template Code between Files Template Parameters Method Templates Template Class Specialization Subclassing Template Classes Inheritance versus Specialization

Function Templates Function Template Specialization Function Template Overloading Friend Function Templates of Class Templates

Advanced Templates More about Template Parameters Template Class Partial Specialization Emulating Function Partial Specialization with Overloading Template Recursion

Summary

Chapter 12: Understanding C++ Quirks and Oddities References Reference Variables Reference Data Members Reference Parameters Reference Return Values Deciding between References and Pointers

x

253 253 256 263 264 267 269 269

270

271 272 273 273 280 281 282 285 290 293 295

295 296 297 298

299 299 307 313 314

322

323 323 324 326 326 327 327

Contents Keyword Confusion The const Keyword The static Keyword Order of Initialization of Nonlocal Variables

Types and Casts typedefs Casts

Scope Resolution Header Files C Utilities Variable-Length Argument Lists Preprocessor Macros

Summary

330 330 333 336

337 337 338

343 343 345 345 347

348

Part III: Mastering Advanced Features of C++ Chapter 13: Effective Memory Management Working with Dynamic Memory How to Picture Memory Allocation and Deallocation Arrays Working with Pointers

Array-Pointer Duality Arrays Are Pointers! Not All Pointers Are Arrays!

Dynamic Strings C-Style Strings String Literals The C++ string Class

Low-Level Memory Operations Pointer Arithmetic Custom Memory Management Garbage Collection Object Pools Function Pointers

Common Memory Pitfalls Underallocating Strings Memory Leaks Double-Deleting and Invalid Pointers Accessing Out-of-Bounds Memory

Summary

349 349 350 351 353 360

362 363 364

365 365 366 367

369 369 370 370 371 372

374 374 374 377 378

378

xi

Contents Chapter 14: Demystifying C++ I/O Using Streams What Is a Stream, Anyway? Stream Sources and Destinations Output with Streams Input with Streams Input and Output with Objects

String Streams File Streams Jumping around with seek() and tell() Linking Streams Together

Bidirectional I/O Internationalization Wide Characters Non-Western Character Sets Locales and Facets

Summary

Chapter 15: Handling Errors Errors and Exceptions What Are Exceptions, Anyway? Why Exceptions in C++ Are a Good Thing Why Exceptions in C++ Are a Bad Thing Our Recommendation

Exception Mechanics Throwing and Catching Exceptions Exception Types Throwing and Catching Multiple Exceptions Uncaught Exceptions Throw Lists

Exceptions and Polymorphism The Standard Exception Hierarchy Catching Exceptions in a Class Hierarchy Writing Your Own Exception Classes

xii

379 379 380 380 380 384 389

390 392 392 395

396 397 397 398 398

400

401 402 402 403 404 404

404 405 406 408 411 412

416 416 417 419

Stack Unwinding and Cleanup

422

Catch, Cleanup, and Rethrow Use Smart Pointers

423 424

Contents Common Error-Handling Issues Memory Allocation Errors Errors in Constructors Errors in Destructors

Putting It All Together Summary

424 424 427 428

428 430

Part IV: Ensuring Bug-Free Code Chapter 16: Overloading C++ Operators Overview of Operator Overloading

431 432

Why Overload Operators? Limitations to Operator Overloading Choices in Operator Overloading Operators You Shouldn’t Overload Summary of Overloadable Operators

432 432 433 435 435

Overloading the Arithmetic Operators

438

Overloading Unary Minus and Unary Plus Overloading Increment and Decrement

Overloading the Bitwise and Binary Logical Operators Overloading the Insertion and Extraction Operators Overloading the Subscripting Operator Providing Read-Only Access with operator[] Non-Integral Array Indices

Overloading the Function Call Operator Overloading the Dereferencing Operators Implementing operator* Implementing operator-> What in the World Is operator->* ?

Writing Conversion Operators Ambiguity Problems with Conversion Operators Conversions for Boolean Expressions

438 439

441 441 443 446 447

448 449 451 452 452

453 454 455

Overloading the Memory Allocation and Deallocation Operators

457

How new and delete Really Work Overloading operator new and operator delete Overloading operator new and operator delete with Extra Parameters

457 459 461

Summary

463

xiii

Contents Chapter 17: Writing Efficient C++ Overview of Performance and Efficiency Two Approaches to Efficiency Two Kinds of Programs Is C++ an Inefficient Language?

Language-Level Efficiency Handle Objects Efficiently Don’t Overuse Costly Language Features Use Inline Methods and Functions

Design-Level Efficiency Cache as Much as Possible Use Object Pools Use Thread Pools

Profiling Profiling Example with gprof

Summary

Chapter 18: Developing Cross-Platform and Cross-Language Applications

465 465 466 466 466

467 467 471 472

472 472 473 479

479 479

488

489

Cross-Platform Development

489

Architecture Issues Implementation Issues Platform-Specific Features

490 492 493

Cross-Language Development Mixing C and C++ Shifting Paradigms Linking with C Code Mixing Java and C++ with JNI Mixing C++ with Perl and Shell Scripts Mixing C++ with Assembly Code

Summary

Chapter 19: Becoming Adept at Testing Quality Control Whose Responsibility Is Testing? The Life Cycle of a Bug Bug-Tracking Tools

Unit Testing Approaches to Unit Testing The Unit Testing Process Unit Testing in Action

xiv

494 494 495 498 499 501 504

505

507 507 508 508 509

510 511 512 515

Contents Higher-Level Testing

523

Integration Tests System Tests Regression Tests

523 525 525

Tips for Successful Testing Summary

526 526

Chapter 20: Conquering Debugging

527

The Fundamental Law of Debugging Bug Taxonomies Avoiding Bugs Planning for Bugs

527 528 528 528

Error Logging Debug Traces Asserts

Debugging Techniques Reproducing Bugs Debugging Reproducible Bugs Debugging Nonreproducible Bugs Debugging Memory Problems Debugging Multithreaded Programs Debugging Example: Article Citations Lessons from the ArticleCitations Example

Summary

Chapter 21: Delving into the STL: Containers and Iterators Containers Overview Requirements on Elements Exceptions and Error Checking Iterators

Sequential Containers Vector The vector Specialization deque list

Container Adapters queue priority_queue stack

528 530 540

541 541 542 543 544 547 548 559

559

561 562 562 563 564

565 566 583 584 584

588 588 591 594

xv

Contents Associative Containers

595

The pair Utility Class map multimap set multiset

595 596 604 608 610

Other Containers Arrays as STL Containers Strings as STL Containers Streams as STL Containers bitset

Summary

611 611 612 613 613

618

Part V: Using Libraries and Patterns Chapter 22: Mastering STL Algorithms and Function Objects Overview of Algorithms The find() and find_if() Algorithms The accumulate() Algorithms

Function Objects Arithmetic Function Objects Comparison Function Objects Logical Function Objects Function Object Adapters Writing Your Own Function Objects

Algorithm Details Utility Algorithms Nonmodifying Algorithms Modifying Algorithms Sorting Algorithms Set Algorithms

Algorithms and Function Objects Example: Auditing Voter Registrations The Voter Registration Audit Problem Statement The auditVoterRolls() Function The getDuplicates() Function The RemoveNames Functor The NameInList Functor Testing the auditVoterRolls() Function

Summary

xvi

619 620 620 623

624 624 625 627 627 630

631 632 633 639 643 646

648 648 648 649 650 651 652

653

Contents Chapter 23: Customizing and Extending the STL

655

Allocators Iterator Adapters

656 656

Reverse Iterators Stream Iterators Insert Iterators

656 657 658

Extending the STL

660

Why Extend the STL? Writing an STL Algorithm Writing an STL Container

Summary

Chapter 24: Exploring Distributed Objects The Appeal of Distributed Computing Distribution for Scalability Distribution for Reliability Distribution for Centrality Distributed Content Distributed versus Networked

Distributed Objects Serialization and Marshalling Remote Procedure Calls

CORBA Interface Definition Language Implementing the Class Using the Objects

XML A Crash Course in XML XML as a Distributed Object Technology Generating and Parsing XML in C++ XML Validation Building a Distributed Object with XML SOAP (Simple Object Access Protocol)

Summary

Chapter 25: Incorporating Techniques and Frameworks “I Can Never Remember How to . . .” . . . Write a Class . . . Subclass an Existing Class

660 660 662

691

693 693 693 694 694 695 695

696 696 700

702 702 704 706

709 709 712 712 721 723 726

728

729 730 730 731

xvii

Contents . . . .

. . . .

. . . .

Throw and Catch Exceptions Read from a File Write to a File Write a Template Class

There Must Be a Better Way Smart Pointers with Reference Counting Double Dispatch Mix-In Classes

Object-Oriented Frameworks Working with Frameworks The Model-View-Controller Paradigm

Summary

Chapter 26: Applying Design Patterns The Singleton Pattern Example: A Logging Mechanism Implementation of a Singleton Using a Singleton

The Factory Pattern Example: A Car Factory Simulation Implementation of a Factory Using a Factory Other Uses of Factories

The Proxy Pattern Example: Hiding Network Connectivity Issues Implementation of a Proxy Using a Proxy

The Adapter Pattern Example: Adapting an XML Library Implementation of an Adapter Using an Adapter

The Decorator Pattern Example: Defining Styles in Web Pages Implementation of a Decorator Using a Decorator

The Chain of Responsibility Pattern Example: Event Handling Implementation of a Chain of Responsibility Using a Chain of Responsibility

xviii

732 733 734 734

736 736 741 747

750 750 750

752

753 754 754 754 759

760 760 762 764 766

766 766 767 767

768 768 768 772

773 773 774 775

776 776 777 778

Contents The Observer Pattern Example: Event Handling Implementation of an Observer Using an Observer

Summary

Appendix A: C++ Interviews Chapter 1: A Crash Course in C++ Chapter 2: Designing Professional C++ Programs Chapter 3: Designing with Objects Chapter 4: Designing with Libraries and Patterns Chapter 5: Designing for Reuse Chapter 6: Maximizing Software Engineering Methods Chapter 7: Coding with Style Chapters 8 and 9: Classes and Objects Chapter 10: Discovering Inheritance Techniques Chapter 11: Writing Generic Code with Templates Chapter 12: Understanding C++ Quirks and Oddities Chapter 13: Effective Memory Management Chapter 14: Demystifying C++ I/O Chapter 15: Handling Errors Chapter 16: Overloading C++ Operators Chapter 17: Writing Efficient C++ Chapter 18: Developing Cross-Platform and Cross-Language Applications Chapter 19: Becoming Adept at Testing Chapter 20: Conquering Debugging Chapters 21, 22, and 23: The Standard Template Library Chapter 24: Exploring Distributed Objects Chapter 25: Incorporating Techniques and Frameworks Chapter 26: Applying Design Patterns

Appendix B: Annotated Bibliography C++ Beginning C++ General C++ I/O Streams The C++ Standard Library C++ Templates

778 778 778 780

781

783 783 784 785 786 787 787 788 789 792 793 793 794 795 796 796 797 798 798 799 799 800 801 801

803 803 803 804 805 805 806

xix

Contents C Integrating C++ and Other Languages Algorithms and Data Structures Open-Source Software Software-Engineering Methodology Programming Style Computer Architecture Efficiency Testing Debugging Distributed Objects CORBA XML and SOAP

810 810

Design Patterns

811

Index

xx

806 806 807 807 807 808 809 809 809 809 810

813

Introduction For many years, C++ has served as the de facto language for writing fast, powerful, and enterprise-class object-oriented programs. As popular as C++ has become, the language is surprisingly difficult to grasp in full. There are simple, but powerful, techniques that professional C++ programmers use that don’t show up in traditional texts, and there are useful parts of C++ that remain a mystery even to experienced C++ programmers. Too often, programming books focus on the syntax of the language instead of its real-world use. The typical C++ text introduces a major part of the language in each chapter, explaining the syntax and providing an example. Professional C++ does not follow this pattern. Instead of giving you just the nuts and bolts of the language with little real-world context, this book will teach you how to use C++ in the real world. It will show you the little-known features that will make your life easier and the reusable coding patterns that separate novice programmers from professional programmers.

Who This Book Is For Even if you have used the language for years, you might still be unfamiliar with the more advanced features of C++ or might not be using the full capabilities of the language. Perhaps you write competent C++ code, but would like to learn more about design in C++ and good programming style. Or maybe you’re relatively new to C++, but want to learn the “right” way to program from the start. This book will bring your C++ skills to the professional level. Because this book focuses on advancing from basic or intermediate knowledge of C++ to becoming a professional C++ programmer, it assumes some knowledge of the language. Chapter 1 covers the basics of C++ as a refresher, but it is not a substitute for actual training and use of the language. If you are just starting with C++, but you have significant experience in C, you should be able to pick up most of what you need from Chapter 1. In any case, you should have a solid foundation in programming fundamentals. You should know about loops, functions, and variables. You should know how to structure a program, and you should be familiar with fundamental techniques like recursion. You should have some knowledge of common data structures like hash tables and queues, and useful algorithms such as sorting and searching. You don’t need to know about object-oriented programming just yet—that is covered in Chapter 3. You will also need to be familiar with the compiler you will be using to develop your code. This book does not provide directions for using individual compilers. Refer to the documentation that came with your compiler for a refresher.

What This Book Covers Professional C++ is an approach to C++ programming that will both increase the quality of your code and improve your programming efficiency. Professional C++ teaches more than just the syntax and language features of C++. It also emphasizes programming methodologies, reusable design patterns, and good

xxi

Introduction programming style. The Professional C++ methodology incorporates the entire software development process—from designing and writing code to testing, debugging, and working in groups. This approach will enable you to master the C++ language and its idiosyncrasies, as well as take advantage of its powerful capabilities for large-scale software development. Imagine someone who has learned all of the syntax of C++ without seeing a single example of its use. He knows just enough to be dangerous! Without examples, he might assume that all code should go in the main() function of the program or that all variables should be global—practices that are generally not considered hallmarks of good programming. Professional C++ programmers understand the correct way to use the language, in addition to the syntax. They recognize the importance of good design, the theories of object-oriented programming, and the best ways to use existing libraries. They have also developed an arsenal of useful code and reusable ideas. By reading this book, you will become a professional C++ programmer. You will expand your knowledge of C++ to cover lesser-known and often misunderstood language features. You will gain an appreciation for object-oriented design and acquire top-notch debugging skills. Perhaps most importantly, you will finish this book armed with a wealth of reusable ideas that can be applied to your actual daily work. There are many good reasons to make the effort to be a professional C++ programmer, as opposed to a programmer who knows C++. Understanding the true workings of the language will improve the quality of your code. Learning about different programming methodologies and processes will help you to work better with your team. Discovering reusable libraries and common design patterns will improve your daily efficiency and help you stop reinventing the wheel. All of these lessons will make you a better programmer and a more valuable employee. While this book can’t guarantee you a promotion, it certainly won’t hurt!

How This Book Is Structured This book is made up of six parts. Part I, “Introduction to Professional C++ Design,” begins with a crash course in C++ basics to ensure a foundation of C++ knowledge. Following the crash course, Part I explores C++ design methodologies. You will read about the importance of design, the object-oriented methodology, the use of libraries and patterns, the importance of code reuse, and the engineering practices being used by programming organizations today. Part II, “Coding C++ the Professional Way,” provides a technical tour of C++ from the Professional point-of-view. You will read about how to write readable C++ code, how to create reusable classes, and how to leverage important language features like inheritance and templates. Part III, “Mastering Advanced Features of C++,” demonstrates how you can get the most out of C++. This part of the book exposes the mysteries of C++ and describes how to use some of its more advanced features. You will read about the unusual and quirky parts of the language, the best ways to manage memory in C++, techniques for input and output, professional-grade error handling, advanced operator overloading, how to write efficient C++ code, and how to write cross-language and cross-platform code.

xxii

Introduction Part IV, “Ensuring Bug-Free Code,” focuses on writing enterprise-quality software. You’ll read about software testing concepts, such as unit testing and regression testing. You’ll also read about techniques used to debug C++ programs. Part V, “Using Libraries and Patterns,” covers the use of libraries and patterns, which enable you to write better code with less work. You’ll read about the standard library included with C++, including advanced topics such as extending the Standard Library. You’ll also read about distributed objects, reusable C++ design techniques, and conceptual object-oriented design patterns. The book concludes with a useful chapter-by-chapter guide to succeeding in a C++ technical interview. You will also a find a practical reference guide to the C++ Standard Library on the supplemental Web site for this book at www.wrox.com.

What You Need to Use This Book All you need to use this book is any computer with a C++ compiler. While compilers often differ in their interpretations of the language, this book focuses on the parts of C++ that have been standardized. The programs in this book have been tested on Windows, Solaris, and Linux platforms.

Conventions To help you get the most from the text and keep track of what’s happening, we’ve used a number of conventions throughout the book.

Boxes like this one hold important, not-to-be forgotten information that is directly relevant to the surrounding text.

Tips, hints, tricks, and asides to the current discussion are offset and placed in italics like this. As for styles in the text: ❑

We highlight important words when we introduce them



We show keyboard strokes like this: Ctrl+A



We show filenames, URLs, and code within the text like so: monkey.cpp.



We present code in two different ways:

In code examples we highlight new and important code with a gray background. The gray highlighting is not used for code that’s less important in the present context or that has been shown before.

xxiii

Introduction

Source Code As you work through the examples in this book, you may choose either to type in all the code manually or to use the source code files that accompany the book. All of the source code used in this book is available for download at www.wrox.com. Once at the site, simply locate the book’s title (either by using the Search box or by using one of the title lists), and click the Download Code link on the book’s detail page to obtain all the source code for the book. Because many books have similar titles, you may find it easiest to search by ISBN; for this book the ISBN is 0-7645-7484-1. Once you download the code, just decompress it with your favorite compression tool. Alternately, you can go to the main Wrox code download page at www.wrox.com/dynamic/books/download.aspx to see the code available for this book and all other Wrox books.

Errata We make every effort to ensure that there are no errors in the text or in the code. However, no one is perfect, and mistakes do occur. If you find an error in one of our books, such as a spelling mistake or faulty piece of code, we would be very grateful for your feedback. By sending in errata you may save another reader hours of frustration, and at the same time you will be helping us provide even higher-quality information. To find the errata page for this book, go to www.wrox.com and locate the title using the Search box or one of the title lists. Then, on the book details page, click the Book Errata link. On this page you can view all errata that has been submitted for this book and posted by Wrox editors. A complete book list including links to each’s book’s errata is also available at www.wrox.com/misc-pages/booklist.shtml. If you don’t spot “your” error on the Book Errata page, go to www.wrox.com/contact/techsupport .shtml and complete the form there to send us the error you have found. We’ll check the information and, if appropriate, post a message to the book’s errata page and fix the problem in subsequent editions of the book.

p2p.wrox.com For author and peer discussion, join the P2P forums at p2p.wrox.com. The forums are a Web-based system for you to post messages relating to Wrox books and related technologies and interact with other readers and technology users. The forums offer a subscription feature to e-mail you topics of interest of your choosing when new posts are made to the forums. Wrox authors, editors, other industry experts, and your fellow readers are present on these forums. At http://p2p.wrox.com you will find a number of different forums that will help you not only as you read this book, but also as you develop your own applications. To join the forums, just follow these steps:

xxiv

Introduction 1. 2. 3.

Go to p2p.wrox.com and click the Register link.

4.

You will receive an e-mail with information describing how to verify your account and complete the joining process.

Read the terms of use and click Agree. Complete the required information to join as well as any optional information you wish to provide and click Submit.

You can read messages in the forums without joining P2P but in order to post your own messages, you must join. Once you join, you can post new messages and respond to messages other users post. You can read messages at any time on the Web. If you would like to have new messages from a particular forum e-mailed to you, click the Subscribe to this Forum icon by the forum name in the forum listing. For more information about how to use the Wrox P2P, be sure to read the P2P FAQs for answers to questions about how the forum software works as well as many common questions specific to P2P and Wrox books. To read the FAQs, click the FAQ link on any P2P page.

xxv

A Crash Course in C++ The goal of this chapter is to cover briefly the most important parts of C++ so that you have a base of knowledge before embarking on the rest of the book. This chapter is not a comprehensive lesson in the C++ programming language. The very basic points (like what a program is and the difference between = and ==) are not covered. The very esoteric points (remember what a union is? how about the volatile keyword?) are also omitted. Certain parts of the C language that are less relevant in C++ are also left out, as are parts of C++ that get in-depth coverage in later chapters. This chapter aims to cover the parts of C++ that programmers encounter on a daily basis. If you’ve been away from C++ for a while and you’ve forgotten the syntax for a for loop, you’ll find that in this chapter. If you’re fairly new to C++ and you don’t understand what a reference variable is, you’ll learn that here as well. If you already have significant experience with C++, skim this chapter to make sure that there aren’t any fundamental parts of the language on which you need to brush up. If you’re new to C++, take the time to read this chapter carefully and make sure that you understand the examples. If you need additional introductory information, consult the titles listed in Appendix B.

The Basics of C++ The C++ language is often viewed as a “better C” or a “superset of C.” Many of the annoyances or rough edges of the C language were addressed when C++ was designed. Because C++ is based on C, much of the syntax you’ll see in this section will look familiar to you if are an experienced C programmer. The two languages certainly have their differences, though. As evidence, The C++ Programming Language by C++ creator Bjarne Stroustrup weighs in at 911 pages, while Kernighan and Ritchie’s The C Programming Language is a scant 274 pages. So if you’re a C programmer, be on the lookout for new or unfamiliar syntax!

Chapter 1

The Obligatory Hello, World In all its glory, the following code is the simplest C++ program you’re likely to encounter. // helloworld.cpp #include int main(int argc, char** argv) { std::cout

710

Exploring Distributed Objects The document prolog is a special type of tag, a piece of syntax that XML recognizes as having some sort of meaning. If you have written HTML files, you’re already familiar with tags. The body of an XML document is made up of element tags. They are simply markers that identify the start and end of a logical piece of the structure. In XML, every starting element tag has a corresponding ending element tag. For example, the following line of XML uses the tag sentence to mark the start and end of a sentence element. Let’s go get some ice cream.

In XML, the end tag is written as a slash followed by the name of the element. Element tags don’t always have to contain data as the previous example does. In XML, you can have an empty tag, which simply exists on its own. One way of doing this is to follow a start tag immediately with an end tag:

XML also provides a shorthand for empty element tags. If you end a tag with a slash, it serves as both the start tag and the end of the element:

The topmost element, which contains all other elements in the document, is known as the root element. In addition to its name, an element tag can contain key/value pairs called attributes. There are no set-instone rules about what can be written as an attribute (remember: XML is just a syntax) but in general, attributes provide metainformation about the element. For example, the sentence element could have an attribute that gives the speaker of the sentence: Let’s go get some ice cream.

Elements can have multiple attributes, though they must have unique keys: Let’s go get some ice cream.

When you see an XML element whose name has a colon in it, such as , the string prior to the colon, is its namespace. Just like namespaces in C++, namespaces in XML allow you to segment the use of names. In the previous examples, the content of an element was either empty or textual data, commonly referred to as a text node. In XML, elements can also contain other elements, which gives XML its hierarchical structure. In the following example, the dialogue element is made up of two sentence elements. Note that the indentation exists only for readability — XML ignores white space between tags.

Let’s go get some ice cream. After I’m done writing this C++ book.

Those are the basics! Elements, attributes, and text nodes are the building blocks of XML. For more advanced syntax, such as special character escaping, consult one of the XML reference books listed in Appendix B.

711

Chapter 24

XML as a Distributed Object Technology Since XML is simple and easy to work with, it has become popular as a mechanism for serialization. XML serialized objects can be sent across a network, and the sender can be confident that the recipient will be able to parse them, regardless of their platform. For example, consider the simple class shown here: class Simple { public: std::string mName; int mPriority; std::string mData; };

An object of type Simple could be serialized to the following XML: this is the data

Of course, since XML doesn’t specify how individual nodes should be used, you could just as easily serialize it as follows:

As long as the recipient of the serialized XML is aware of the rules you are using to serialize the object, they should be able to deserialize it. XML serialization has increased in popularity as a simpler alternative to heavyweight distributed object technologies such as CORBA. XML has a much more gradual learning curve than CORBA and offers many of the same benefits, such as platform and language independence.

Generating and Parsing XML in C++ Because XML is merely a file format, and not an object description language, the task of converting data to and from XML is left to the programmer. In general, writing XML is the easy part. Reading XML is usually aided by a third-party XML library.

Generating XML To use XML as a serialization technology, your objects will need to be able to convert themselves into XML. In many cases, building a stream of XML on the fly is the easiest way to output XML. In fact, the notion that XML elements are “wrapped” in other elements makes things even easier. You can build new XML documents as amalgams of existing ones. If that sounds a bit complicated, consider the following example. Assume that you have a function called getNextSentenceXML(), which asks the user for a sentence and returns it as an XML representation of the sentence. Because that function returns the sentence as a valid XML element, you could create a dialogue of sentences by wrapping the results of multiple calls to getNextSentenceXML() in a dialogue element tag:

712

Exploring Distributed Objects string getDialogueXML() { sstringstream outStream; // Begin the dialogue element. outStream