324 12 3MB
English Pages 838 [866] Year 2005
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