1. Trang chủ
  2. » Công Nghệ Thông Tin

Thinking in C++ ppt

592 4,4K 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Thinking in C++ 2nd Edition Volume 2: Standard Libraries & Advanced Topics
Tác giả Bruce Eckel
Trường học MindView Inc.
Chuyên ngành Computer Science
Thể loại Sách hướng dẫn/E-book
Năm xuất bản 1999
Định dạng
Số trang 592
Dung lượng 1,99 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

What’s in Volume 2 of this book The completion of the C++ Standard also added a number of important new libraries such as string and the Standard Template Library STL as well as new com

Trang 1

object-

Trang 2

“This book is a tremendous achievement You owe it to yourself to have a copy on your shelf The chapter on iostreams is the most comprehensive and understandable treatment of that subject I’ve seen to date.”

Al Stevens Contributing Editor, Doctor Dobbs Journal

“Eckel’s book is the only one to so clearly explain how to rethink program construction for object orientation That the book is also an excellent tutorial

on the ins and outs of C++ is an added bonus.”

Andrew Binstock Editor, Unix Review

“Bruce continues to amaze me with his insight into C++, and Thinking in

C++ is his best collection of ideas yet If you want clear answers to difficult

questions about C++, buy this outstanding book.”

Gary Entsminger

Author, The Tao of Objects

“Thinking in C++ patiently and methodically explores the issues of when and

how to use inlines, references, operator overloading, inheritance and dynamic objects, as well as advanced topics such as the proper use of templates,

exceptions and multiple inheritance The entire effort is woven in a fabric that includes Eckel’s own philosophy of object and program design A must for

every C++ developer’s bookshelf, Thinking in C++ is the one C++ book you

must have if you’re doing serious development with C++.”

Richard Hale Shaw Contributing Editor, PC Magazine

Trang 3

Thinking

In

C++

2nd Edition, Volume 2 Bruce Eckel

President, MindView Inc.

Trang 4

© 1999 by Bruce Eckel, MindView, Inc

The information in this book is distributed on an “as is” basis, without warranty While every precaution has been taken in the preparation of this book, neither the author nor the publisher shall have any liability to any person or entitle with respect to any liability, loss or damage caused or alleged to be caused directly or indirectly by instructions contained in this book or by the computer software or hardware products described herein

All rights reserved No part of this book may be reproduced in any form or by any electronic or mechanical means including information storage and retrieval systems without permission in writing from the publisher or author, except by a reviewer who may quote brief passages in a review Any of the names used in the examples and text of this book are fictional; any relationship to persons living or dead

or to fictional characters in other works is purely coincidental

Trang 5

dedication

To the scholar, the healer, and the muse

Trang 6

What’s inside

Thinking in C++ 2 nd edition Volume 2: Standard Libraries & Advanced Topics Revision 1, xx 1999 1

Preface 13 What’s new in the second edition13 What’s in Volume 2 of this book 14

How to get Volume 2 14

Prerequisites 14

Learning C++ 14

Goals 16

Chapters 17

Exercises 18

Exercise solutions 18

Source code 18

Language standards 20

Language support 20

The book’s CD ROM 20

Seminars, CD Roms & consulting20 Errors 21

Acknowledgements 21

Part 1: The Standard C++ Library 23 Library overview 24

1: Strings 27 What’s in a string 27

Creating and initializing C++ strings 29 Operating on strings 31

Appending, inserting and concatenating strings 32 Replacing string characters 34

Concatenation using non-member overloaded operators 37 Searching in strings 38

Finding in reverse 43

Finding first/last of a set 44

Removing characters from strings 45

Comparing strings 49

Using iterators 53

Trang 7

Strings and character traits 55

A string application 58

Summary 61

Exercises 62

2: Iostreams 63 Why iostreams? 63

True wrapping 65

Iostreams to the rescue 67

Sneak preview of operator overloading68 Inserters and extractors 69

Common usage 70

Line-oriented input 72

File iostreams 74

Open modes 76

Iostream buffering 76

Using get( ) with a streambuf 78

Seeking in iostreams 78

Creating read/write files 80

stringstreams 81

strstreams 81

User-allocated storage 81

Automatic storage allocation 84

Output stream formatting 87

Internal formatting data 88

An exhaustive example 92

Formatting manipulators 95

Manipulators with arguments 96

Creating manipulators 99

Effectors 100

Iostream examples 102

Code generation 102

A simple datalogger 110

Counting editor 117

Breaking up big files 118

Summary 120

Exercises 120

3: Templates in depth 121 Nontype template arguments 121

Default template arguments 122

The typename keyword 122

Typedefing a typename 124

Using typename instead of class 124

Function templates 124

A string conversion system 125

A memory allocation system 126

Type induction in function templates 129

Taking the address of a generated function template 130

Trang 8

Local classes in templates 131

Applying a function to an STL sequence 131 Template-templates 134

Member function templates 135

Why virtual member template functions are disallowed 137 Nested template classes 137

Template specializations 137

Full specialization 137

Partial Specialization 137

A practical example 137

Design & efficiency 141

Preventing template bloat 141

Explicit instantiation 143

Explicit specification of template functions 144 Controlling template instantiation144 The inclusion vs separation models145 The export keyword 145

Template programming idioms 145 The “curiously-recurring template”.145 Traits 145

Summary 145

4: STL Containers & Iterators147 Containers and iterators 147

STL reference documentation 149

The Standard Template Library 149 The basic concepts 151

Containers of strings 155

Inheriting from STL containers 157 A plethora of iterators 159

Iterators in reversible containers 161

Iterator categories 162

Predefined iterators 163

Basic sequences: vector, list & deque 169 Basic sequence operations 169

vector 172

Cost of overflowing allocated storage173 Inserting and erasing elements 177

deque 179

Converting between sequences 181

Cost of overflowing allocated storage182 Checked random-access 184

list 185

Special list operations 187

Swapping all basic sequences 191

Robustness of lists 192

Performance comparison 193

set 198

Eliminating strtok( ) 199

StreamTokenizer: a more flexible solution 201

Trang 9

A completely reusable tokenizer 203

stack 208

queue 211

Priority queues 216

Holding bits 226

bitset<n> 226

vector<bool> 230

Associative containers 232

Generators and fillers for associative containers 236 The magic of maps 239

Multimaps and duplicate keys 244

Multisets 247

Combining STL containers 250

Cleaning up containers of pointers253 Creating your own containers 255

Freely-available STL extensions257 Summary 259

Exercises 260

5: STL Algorithms 263 Function objects 263

Classification of function objects 264

Automatic creation of function objects265 SGI extensions 279

A catalog of STL algorithms 285

Support tools for example creation 287

Filling & generating 291

Counting 293

Manipulating sequences 294

Searching & replacing 299

Comparing ranges 305

Removing elements 308

Sorting and operations on sorted ranges311 Heap operations 322

Applying an operation to each element in a range 323 Numeric algorithms 331

General utilities 334

Creating your own STL-style algorithms 336 Summary 337

Exercises 337

Part 2: Advanced Topics 341 6: Multiple inheritance 342 Perspective 342

Duplicate subobjects 344

Ambiguous upcasting 345

virtual base classes 346

Trang 10

The "most derived" class and virtual base initialization 348

"Tying off" virtual bases with a default constructor 349

Overhead 351

Upcasting 352

Persistence 355

Avoiding MI 362

Repairing an interface 362

Summary 367

Exercises 368

7: Exception handling 369 Error handling in C 369

Throwing an exception 372

Catching an exception 373

The try block 373

Exception handlers 373

The exception specification 374

Better exception specifications? 377

Catching any exception 377

Rethrowing an exception 378

Uncaught exceptions 378

Function-level try blocks 380

Cleaning up 380

Constructors 384

Making everything an object 386

Exception matching 388

Standard exceptions 390

Programming with exceptions 391 When to avoid exceptions 391

Typical uses of exceptions 392

Overhead 396

Summary 397

Exercises 397

8: Run-time type identification399 The “Shape” example 399

What is RTTI? 400

Two syntaxes for RTTI 400

Syntax specifics 404

typeid( ) with built-in types 404

Producing the proper type name 405

Nonpolymorphic types 405

Casting to intermediate levels 406

void pointers 408

Using RTTI with templates 408

References 409

Exceptions 410

Multiple inheritance 411

Trang 11

Sensible uses for RTTI 412

Revisiting the trash recycler 413

Mechanism & overhead of RTTI416 Creating your own RTTI 416

Explicit cast syntax 420

Summary 421

Exercises 422

9: Building stable systems 423 Shared objects & reference counting 423 Reference-counted class hierarchies423 The canonical object & singly-rooted hierarchies 423 An extended canonical form 424

Design by contract 424

Integrated unit testing 424

Dynamic aggregation 424

Exercises 428

10: Design patterns 429 The pattern concept 429

The singleton 430

Classifying patterns 434

Features, idioms, patterns 435

Basic complexity hiding 435

Factories: encapsulating object creation 436 Polymorphic factories 438

Abstract factories 441

Virtual constructors 444

Callbacks 449

Functor/Command 450

Strategy 450

Observer 450

Multiple dispatching 459

Visitor, a type of multiple dispatching463 Efficiency 466

Flyweight 466

The composite 466

Evolving a design: the trash recycler 466 Improving the design 471

“Make more objects” 471

A pattern for prototyping creation 476

Abstracting usage 488

Applying double dispatching 492

Implementing the double dispatch 492

Applying the visitor pattern 497

RTTI considered harmful? 503

Summary 506

Trang 12

Exercises 507

11: Tools & topics 509 The code extractor 509

Debugging 531

assert( ) 531

Trace macros 531

Trace file 532

Abstract base class for debugging 533

Tracking new/delete & malloc/free533 CGI programming in C++ 539

Encoding data for CGI 540

The CGI parser 541

Using POST 548

Handling mailing lists 549

A general information-extraction CGI program 560 Parsing the data files 566

Summary 573

Exercises 573

A: Recommended reading 575 C 575

General C++ 575

My own list of books 576

Depth & dark corners 576

The STL 576

Design Patterns 576

Index 580

Trang 13

Preface

Like any human language, C++ provides a way to express

concepts If successful, this medium of expression will be

significantly easier and more flexible than the alternatives as

problems grow larger and more complex

You can’t just look at C++ as a collection of features; some of the features make no sense in

isolation You can only use the sum of the parts if you are thinking about design, not simply

coding And to understand C++ in this way, you must understand the problems with C and

with programming in general This book discusses programming problems, why they are

problems, and the approach C++ has taken to solve such problems Thus, the set of features I

explain in each chapter will be based on the way that I see a particular type of problem being

solved with the language In this way I hope to move you, a little at a time, from

understanding C to the point where the C++ mindset becomes your native tongue

Throughout, I’ll be taking the attitude that you want to build a model in your head that allows

you to understand the language all the way down to the bare metal; if you encounter a puzzle

you’ll be able to feed it to your model and deduce the answer I will try to convey to you the

insights which have rearranged my brain to make me start “thinking in C++.”

What’s new in the second

edition

This book is a thorough rewrite of the first edition to reflect all the changes introduced in C++

by the finalization of the ANSI/ISO C++ Standard The entire text present in the first edition

has been examined and rewritten, sometimes removing old examples, often changing existing

examples and adding new ones, and adding many new exercises Significant rearrangement

and re-ordering of the material took place to reflect the availability of better tools and my

improved understanding of how people learn C++ A new chapter was added which is a rapid

introduction to the C concepts and basic C++ features for those who haven’t been exposed

The CD ROM bound into the back of the book contains a seminar which is an even gentler

introduction to the C concepts necessary to understand C++ (or Java) It was created by

Chuck Allison for my company (MindView, Inc.) and it’s called “Thinking in C: Foundations

for Java and C++.” It introduces you to the aspects of C that are necessary for you to move on

Trang 14

to C++ or Java (leaving out the nasty bits that C programmers must deal with on a day-to-day

basis but that the C++ and Java languages steer you away from)

So the short answer is: what isn’t brand new has been rewritten, sometimes to the point where

you wouldn’t recognize the original examples and material

What’s in Volume 2 of this book

The completion of the C++ Standard also added a number of important new libraries such as

string and the Standard Template Library (STL) as well as new complexity in templates

These and other more advanced topics have been relegated to Volume 2 of this book,

including issues like multiple inheritance, exception handling, design patterns and topics

about building stable systems and debugging them

How to get Volume 2

Just like the book that you currently hold, Thinking in C++, Volume 2 is freely downloadable

in its entirety from my web site at www.BruceEckel.com The final version of Volume 2 will

be completed and printed in late 2000 or early 2001

The web site also contains the source code for both the books, along with updates and

information about CD ROMs, public seminars, and in-house training, consulting, mentoring

and walk-throughs

Prerequisites

In the first edition of this book, I decided to assume that someone else had taught you C and

that you have at least a reading level of comfort with it My primary focus was on simplifying

what I found difficult – the C++ language In this edition I have added a chapter that is a very

rapid introduction to C, along with the Thinking in C seminar-on-CD, but still assuming that

you have some kind of programming experience already In addition, just as you learn many

new words intuitively by seeing them in context in a novel, it’s possible to learn a great deal

about C from the context in which it is used in the rest of the book

Learning C++

I clawed my way into C++ from exactly the same position as I expect many of the readers of

this book will: As a programmer with a very no-nonsense, nuts-and-bolts attitude about

programming Worse, my background and experience was in hardware-level embedded

programming, where C has often been considered a high-level language and an inefficient

overkill for pushing bits around I discovered later that I wasn’t even a very good C

programmer, hiding my ignorance of structures, malloc( ) & free( ), setjmp( ) & longjmp( ),

Trang 15

and other “sophisticated” concepts, scuttling away in shame when the subjects came up in

conversation rather than reaching out for new knowledge

When I began my struggle to understand C++, the only decent book was Stroustrup’s

self-professed “expert’s guide,1 ” so I was left to simplify the basic concepts on my own This

resulted in my first C++ book,2 which was essentially a brain dump of my experience That

was designed as a reader’s guide, to bring programmers into C and C++ at the same time

Both editions3 of the book garnered an enthusiastic response

At about the same time that Using C++ came out, I began teaching the language in live

seminars and presentations Teaching C++ (and later, Java) became my profession; I’ve seen

nodding heads, blank faces, and puzzled expressions in audiences all over the world since

1989 As I began giving in-house training with smaller groups of people, I discovered

something during the exercises Even those people who were smiling and nodding were

confused about many issues I found out, by creating and chairing the C++ and Java tracks at

the Software Development Conference for many years, that I and other speakers tended to

give the typical audience too many topics, too fast So eventually, through both variety in the

audience level and the way that I presented the material, I would end up losing some portion

of the audience Maybe it’s asking too much, but because I am one of those people resistant to

traditional lecturing (and for most people, I believe, such resistance results from boredom), I

wanted to try to keep everyone up to speed

For a time, I was creating a number of different presentations in fairly short order Thus, I

ended up learning by experiment and iteration (a technique that also works well in C++

program design) Eventually I developed a course using everything I had learned from my

teaching experience It tackles the learning problem in discrete, easy-to-digest steps and for a

hands-on seminar (the ideal learning situation), there are exercises following each of the

presentations

The first edition of this book developed over the course of twoyears, and the material in this

book has been road-tested in many forms in many different seminars The feedback that I’ve

gotten from each seminar has helped me change and refocus the material until I feel it works

well as a teaching medium But it isn’t just a seminar handout – I tried to pack as much

information as I could within these pages, and structure it to draw you through, onto the next

subject More than anything, the book is designed to serve the solitary reader, struggling with

a new programming language

Trang 16

Goals

My goals in this book are to:

1 Present the material a simple step at a time, so the reader can easily digest

each concept before moving on

2 Use examples that are as simple and short as possible This sometimes

prevents me from tackling “real-world” problems, but I’ve found that beginners are usually happier when they can understand every detail of an example rather than being impressed by the scope of the problem it solves

Also, there’s a severe limit to the amount of code that can be absorbed in a classroom situation For this I sometimes receive criticism for using “toy examples,” but I’m willing to accept that in favor of producing something pedagogically useful

3 Carefully sequence the presentation of features so that you aren’t seeing

something you haven’t been exposed to Of course, this isn’t always possible; in those situations, a brief introductory description will be given

4 Give you what I think is important for you to understand about the

language, rather than everything I know I believe there is an “information importance hierarchy,” and there are some facts that 95% of programmers will never need to know, but that would just confuse people and add to their perception of the complexity of the language To take an example from C, if you memorize the operator precedence table (I never did) you can write

clever code But if you have to think about it, it will confuse the

reader/maintainer of that code So forget about precedence, and use parentheses when things aren’t clear This same attitude will be taken with some information in the C++ language, which I think is more important for compiler writers than for programmers

5 Keep each section focused enough so the lecture time – and the time

between exercise periods – is small Not only does this keep the audience’

minds more active and involved during a hands-on seminar, but it gives the reader a greater sense of accomplishment

6 Provide the reader with a solid foundation so they can understand the issues

well enough to move on to more difficult coursework and books (in particular, Volume 2 of this book)

7 I’ve endeavored not to use any particular vendor’s version of C++ because,

for learning the language, I don’t feel like the details of a particular

Trang 17

implementation are as important as the language itself Most vendors’

documentation concerning their own implementation specifics is adequate

Chapters

C++ is a language where new and different features are built on top of an existing syntax

(Because of this it is referred to as a hybrid object-oriented programming language.) As more

people have passed through the learning curve, we’ve begun to get a feel for the way

programmers move through the stages of the C++ language features Because it appears to be

the natural progression of the procedurally-trained mind, I decided to understand and follow

this same path, and accelerate the process by posing and answering the questions that came to

me as I learned the language and that came from audiences as I taught it

This course was designed with one thing in mind: to streamline the process of learning the

C++ language Audience feedback helped me understand which parts were difficult and

needed extra illumination In the areas where I got ambitious and included too many features

all at once, I came to know – through the process of presenting the material – that if you

include a lot of new features, you have to explain them all, and the student’s confusion is

easily compounded As a result, I’ve taken a great deal of trouble to introduce the features as

few at a time as possible; ideally, only one major concept at a time per chapter

The goal, then, is for each chapter to teach a single concept, or a small group of associated

concepts, in such a way that no additional features are relied upon That way you can digest

each piece in the context of your current knowledge before moving on To accomplish this, I

leave some C features in place for longer than I would prefer The benefit is that you will not

be confused by seeing all the C++ features used before they are explained, so your

introduction to the language will be gentle and will mirror the way you will assimilate the

features if left to your own devices

Here is a brief description of the chapters contained in this book:

(5) Introduction to iostreams One of the original C++ libraries – the one that provides the

essential I/O facility – is called iostreams Iostreams is intended to replace C’s stdio.h with an

I/O library that is easier to use, more flexible, and extensible – you can adapt it to work with

your new classes This chapter teaches you the ins and outs of how to make the best use of the

existing iostream library for standard I/O, file I/O, and in-memory formatting

(15) Multiple inheritance This sounds simple at first: A new class is inherited from more

than one existing class However, you can end up with ambiguities and multiple copies of

base-class objects That problem is solved with virtual base classes, but the bigger issue

remains: When do you use it? Multiple inheritance is only essential when you need to

manipulate an object through more than one common base class This chapter explains the

syntax for multiple inheritance, and shows alternative approaches – in particular, how

templates solve one common problem The use of multiple inheritance to repair a “damaged”

class interface is demonstrated as a genuinely valuable use of this feature

Trang 18

(16) Exception handling Error handling has always been a problem in programming Even if

you dutifully return error information or set a flag, the function caller may simply ignore it

Exception handling is a primary feature in C++ that solves this problem by allowing you to

“throw” an object out of your function when a critical error happens You throw different

types of objects for different errors, and the function caller “catches” these objects in separate

error handling routines If you throw an exception, it cannot be ignored, so you can guarantee

that something will happen in response to your error

(17) Run-time type identification Run-time type identification (RTTI) lets you find the

exact type of an object when you only have a pointer or reference to the base type Normally,

you’ll want to intentionally ignore the exact type of an object and let the virtual function

mechanism implement the correct behavior for that type But occasionally it is very helpful to

know the exact type of an object for which you only have a base pointer; often this

information allows you to perform a special-case operation more efficiently This chapter

explains what RTTI is for and how to use it

Exercises

I’ve discovered that simple exercises are exceptionally useful during a seminar to complete a

student’s understanding, so you’ll find a set at the end of each chapter

These are fairly simple, so they can be finished in a reasonable amount of time in a classroom

situation while the instructor observes, making sure all the students are absorbing the material

Some exercises are a bit more challenging to keep advanced students entertained They’re all

designed to be solved in a short time and are only there to test and polish your knowledge

rather than present major challenges (presumably, you’ll find those on your own – or more

likely they’ll find you)

Exercise solutions

Solutions to exercises can be found in the electronic document The C++ Annotated Solution

Guide, Volume 2 by Chuck Allison, available for a small fee from www.BruceEckel.com [[

Note this is not yet available ]]

Source code

The source code for this book is copyrighted freeware, distributed via the web site

http://www.BruceEckel.com The copyright prevents you from republishing the code in print

media without permission

Although the code is available in a zipped file on the above web site, you can also unpack the

code yourself by downloading the text version of the book and running the program

ExtractCode (from Volume 2 of this book), the source for which is also provided on the Web

Trang 19

site The program will create a directory for each chapter and unpack the code into those

directories In the starting directory where you unpacked the code you will find the following

copyright notice:

//:! :CopyRight.txt

Copyright (c) Bruce Eckel, 1999

Source code file from the book "Thinking in C++"

All rights reserved EXCEPT as allowed by the

following statements: You can freely use this file

for your own work (personal or commercial),

including modifications and distribution in

executable form only Permission is granted to use

this file in classroom situations, including its

use in presentation materials, as long as the book

"Thinking in C++" is cited as the source

Except in classroom situations, you cannot copy

and distribute this code; instead, the sole

distribution point is http://www.BruceEckel.com

(and official mirror sites) where it is

freely available You cannot remove this

copyright and notice You cannot distribute

modified versions of the source code in this

package You cannot use this file in printed

media without the express permission of the

author Bruce Eckel makes no representation about

the suitability of this software for any purpose

It is provided "as is" without express or implied

warranty of any kind, including any implied

warranty of merchantability, fitness for a

particular purpose or non-infringement The entire

risk as to the quality and performance of the

software is with you Bruce Eckel and the

publisher shall not be liable for any damages

suffered by you or any third party as a result of

using or distributing software In no event will

Bruce Eckel or the publisher be liable for any

lost revenue, profit, or data, or for direct,

indirect, special, consequential, incidental, or

punitive damages, however caused and regardless of

the theory of liability, arising out of the use of

or inability to use software, even if Bruce Eckel

and the publisher have been advised of the

possibility of such damages Should the software

prove defective, you assume the cost of all

Trang 20

necessary servicing, repair, or correction If you

think you've found an error, please submit the

correction using the form you will find at

www.BruceEckel.com (Please use the same

form for non-code errors found in the book.)

///:~

You may use the code in your projects and in the classroom as long as the copyright notice is

retained

Language standards

Throughout this book, when referring to conformance to the ANSI/ISO C standard, I will

generally just say ‘C.’ Only if it is necessary to distinguish between Standard C and older,

pre-Standard versions of C will I make the distinction

At this writing the ANSI/ISO C++ committee was finished working on the language Thus, I

will use the term Standard C++ to refer to the standardized language If I simply refer to C++

you should assume I mean “Standard C++.”

Language support

Your compiler may not support all the features discussed in this book, especially if you don’t

have the newest version of your compiler Implementing a language like C++ is a Herculean

task, and you can expect that the features will appear in pieces rather than all at once But if

you attempt one of the examples in the book and get a lot of errors from the compiler, it’s not

necessarily a bug in the code or the compiler – it may simply not be implemented in your

particular compiler yet

The book’s CD ROM

Seminars, CD Roms &

consulting

My company, MindView, Inc., provides public hands-on training seminars based on the

material in this book, and also for advanced topics Selected material from each chapter

represents a lesson, which is followed by a monitored exercise period so each student receives

personal attention We also provide on-site training, consulting, mentoring, and design & code

Trang 21

walkthroughs Information and sign-up forms for upcoming seminars and other contact

information can be found at http://www.BruceEckel.com

Errors

No matter how many tricks a writer uses to detect errors, some always creep in and these

often leap off the page for a fresh reader If you discover anything you believe to be an error,

please use the correction form you will find at http://www.BruceEckel.com Your help is

appreciated

Acknowledgements

The ideas and understanding in this book have come from many sources: friends like Chuck

Allison, Andrea Provaglio, Dan Saks, Scott Meyers, Charles Petzold, and Michael Wilk;

pioneers of the language like Bjarne Stroustrup, Andrew Koenig, and Rob Murray; members

of the C++ Standards Committee like Nathan Myers (who was particularly helpful and

generous with his insights), Tom Plum, Reg Charney, Tom Penello, Sam Druker, and Uwe

Steinmueller; people who have spoken in my C++ track at the Software Development

Conference; and very often students in my seminars, who ask the questions I need to hear in

order to make the material clearer

I have been presenting this material on tours produced by Miller Freeman Inc with my friend

Richard Hale Shaw Richard’s insights and support have been very helpful (and Kim’s, too)

Thanks also to KoAnn Vikoren, Eric Faurot, Jennifer Jessup, Nicole Freeman, Barbara

Hanscome, Regina Ridley, Alex Dunne, and the rest of the cast and crew at MFI

The book design, cover design, and cover photo were created by my friend Daniel

Will-Harris, noted author and designer, who used to play with rub-on letters in junior high school

while he awaited the invention of computers and desktop publishing However, I produced the

camera-ready pages myself, so the typesetting errors are mine Microsoft® Word for Windows

97 was used to write the book and to create camera-ready pages The body typeface is [Times

for the electronic distribution] and the headlines are in [Times for the electronic distribution]

A special thanks to all my teachers, and all my students (who are my teachers as well)

Personal thanks to my friends Gen Kiyooka and Kraig Brockschmidt The supporting cast of

friends includes, but is not limited to: Zack Urlocker, Andrew Binstock, Neil Rubenking,

Steve Sinofsky, JD Hildebrandt, Brian McElhinney, Brinkley Barr, Larry O’Brien, Bill Gates

at Midnight Engineering Magazine, Larry Constantine & Lucy Lockwood, Tom Keffer, Greg

Perry, Dan Putterman, Christi Westphal, Gene Wang, Dave Mayer, David Intersimone, Claire

Sawyers, Claire Jones, The Italians (Andrea Provaglio, Laura Fallai, Marco Cantu, Corrado,

Ilsa and Christina Giustozzi), Chris & Laura Strand, The Almquists, Brad Jerbic, Marilyn

Cvitanic, The Mabrys, The Haflingers, The Pollocks, Peter Vinci, The Robbins Families, The

Moelter Families (& the McMillans), The Wilks, Dave Stoner, Laurie Adams, The Penneys,

Trang 22

The Cranstons, Larry Fogg, Mike & Karen Sequeira, Gary Entsminger & Allison Brody,

Chester Andersen, Joe Lordi, Dave & Brenda Bartlett, The Rentschlers, The Sudeks, Lynn &

Todd, and their families And of course, Mom & Dad

Trang 23

Part 1: The

Standard C++

Library

Standard C++ not only incorporates all the Standard C

libraries, with small additions and changes to support type

safety, it also adds libraries of its own These libraries are far

more powerful than those in Standard C; the leverage you

get from them is analogous to the leverage you get from

changing from C to C++

This section of the book gives you an in-depth introduction to the most important portions of

the Standard C++ library

The most complete and also the most obscure reference to the full libraries is the Standard

itself Somewhat more readable (and yet still a self-described “expert’s guide”) is Bjarne

Stroustrup’s 3rd Edition of The C++ Programming Language (Addison-Wesley, 1997)

Another valuable reference is the 3rd edition of C++ Primer, by Lippman & Lajoie The goal

of the chapters in this book that cover the libraries is to provide you with an encyclopedia of

descriptions and examples so you’ll have a good starting point for solving any problem that

requires the use of the Standard libraries However, there are some techniques and topics that

are used rarely enough that they are not covered here, so if you can’t find it in these chapters

you should reach for the other two books; this book is not intended to replace those but rather

to complement them In particular, I hope that after going through the material in the

following chapters you’ll have a much easier time understanding those books

You will notice that this section does not contain exhaustive documentation describing every

function and class in the Standard C++ library I’ve left the full descriptions to others; in

particular there a particularly good on-line sources of standard library documentation in

HTML format that you can keep resident on your computer and view with a Web browser

whenever you need to look something up This is PJ Plauger’s Dinkumware C/C++ Library

reference at http://www.dinkumware.com You can view this on-line, and purchase it for local

Trang 24

viewing It contains complete reference pages for the both the C and C++ libraries (so it’s good to use for all your Standard C/C++ programming questions) I am particularly fond of electronic documentation not only because you can always have it with you, but also because you can do an electronic search for what you’re seeking

When you’re actively programming, these resources should adequately satisfy your reference needs (and you can use them to look up anything in this chapter that isn’t clear to you) Appendix XX lists additional references

Library overview

[[ Still needs work ]]

The first chapter in this section introduces the Standard C++ string class, which is a powerful tool that simplifies most of the text processing chores you might have to do The string class

may be the most thorough string manipulation tool you’ve ever seen Chances are, anything you’ve done to character strings with lines of code in C can be done with a member function

call in the string class, including append( ), assign( ), insert( ), remove( ), replace( ), resize( ), copy( ), find( ), rfind( ), find_first_of( ), find_last_of( ), find_first_not_of( ), find_last_not_of( ), substr( ), and compare( ) The operators =, +=, and [ ] are also

overloaded to perform the intuitive operations In addition, there’s a “wide” wstring class designed to support international character sets Both string and wstring (declared in

<string>, not to be confused with C’s <string.h>, which is, in strict C++, <cstring>) are created from a common template class called basic_string Note that the string classes are

seamlessly integrated with iostreams, virtually eliminating the need for you to ever use

strstream

The next chapter covers the iostream library

Language Support Elements inherent to the language itself, like implementation limits in

<climits> and <cfloat>; dynamic memory declarations in <new> like bad_alloc (the

exception thrown when you’re out of memory) and set_new_handler; the <typeinfo> header for RTTI and the <exception> header that declares the terminate( ) and unexpected( )

functions

Diagnostics Library Components C++ programs can use to detect and report errors The

<exception> header declares the standard exception classes and <cassert> declares the same thing as C’s assert.h

General Utilities Library These components are used by other parts of the Standard C++

library, but you can also use them in your own programs Included are templatized versions of

operators !=, >, <=, and >= (to prevent redundant definitions), a pair template class with a

tuple-making template function, a set of function objects for support of the STL, and storage

allocation functions for use with the STL so you can easily modify the storage allocation mechanism

Trang 25

Localization Library This allows you to localize strings in your program to adapt to usage

in different countries, including money, numbers, date, time, and so on

Containers Library This includes the Standard Template Library (described in the next section of this appendix) and also the bits and bit_string classes in <bits> and <bitstring>, respectively Both bits and bit_string are more complete implementations of the bitvector concept introduced in Chapter XX The bits template creates a fixed-sized array of bits that can be manipulated with all the bitwise operators, as well as member functions like set( ), reset( ), count( ), length( ), test( ), any( ), and none( ) There are also conversion operators to_ushort( ), to_ulong( ), and to_string( )

The bit_string class is, by contrast, a dynamically sized array of bits, with similar operations

to bits, but also with additional operations that make it act somewhat like a string There’s a fundamental difference in bit weighting: With bits, the right-most bit (bit zero) is the least

significant bit, but with bit_string, the right-most bit is the most significant bit There are no

conversions between bits and bit_string You’ll use bits for a space-efficient set of on-off flags and bit_string for manipulating arrays of binary values (like pixels)

Iterators Library Includes iterators that are tools for the STL (described in the next section

of this appendix), streams, and stream buffers

Algorithms Library These are the template functions that perform operations on the STL containers using iterators The algorithms include: adjacent_find, prev_permutation, binary_search, push_heap, copy, random_shuffle, copy_backward, remove, count, remove_copy, count_if, remove_copy_if, equal, remove_if, equal_range, replace, fill, replace_copy, fill_n, replace_copy_if, find, replace_if, find_if, reverse, for_each,

reverse_copy, generate, rotate, generate_n, rotate_copy, includes, search,

inplace_merge, set_difference, lexicographical_compare, set_intersection, lower_bound, set_symmetric_difference, make_heap, set_union, max, sort, max_element, sort_heap, merge, stable_partition, min, stable_sort, min_element, swap, mismatch, swap_ranges, next_permutation, transform, nth_element, unique, partial_sort, unique_copy,

partial_sort_copy, upper_bound, and partition

Numerics Library The goal of this library is to allow the compiler implementer to take

advantage of the architecture of the underlying machine when used for numerical operations This way, creators of higher level numerical libraries can write to the numerics library and produce efficient algorithms without having to customize to every possible machine The numerics library also includes the complex number class (which appeared in the first version

of C++ as an example, and has become an expected part of the library) in float, double, and long double forms

Trang 27

1: Strings

4One of the biggest time-wasters in C is character arrays:

keeping track of the difference between static quoted strings

and arrays created on the stack and the heap, and the fact

that sometimes you’re passing around a char* and

sometimes you must copy the whole array

(This is the general problem of shallow copy vs deep copy.) Especially because string

manipulation is so common, character arrays are a great source of misunderstandings and

bugs

Despite this, creating string classes remained a common exercise for beginning C++

programmers for many years The Standard C++ library string class solves the problem of

character array manipulation once and for all, keeping track of memory even during

assignments and copy-constructions You simply don’t need to think about it

This chapter examines the Standard C++ string class, beginning with a look at what

constitutes a C++ string and how the C++ version differs from a traditional C character array

You’ll learn about operations and manipulations using string objects, and see how C++

strings accommodate variation in character sets and string data conversion

Handling text is perhaps one of the oldest of all programming applications, so it’s not

surprising that the C++ string draws heavily on the ideas and terminology that have long been

used for this purpose in C and other languages As you begin to acquaint yourself with C++

strings this fact should be reassuring, in the respect that no matter what programming idiom

you choose, there are really only about three things you can do with a string: create or modify

the sequence of characters stored in the string, detect the presence or absence of elements

within the string, and translate between various schemes for representing string characters

You’ll see how each of these jobs is accomplished using C++ string objects

What’s in a string

In C, a string is simply an array of characters that always includes a binary zero (often called

the null terminator) as its final array element There are two significant differences between

4 Much of the material in this chapter was originally created by Nancy Nicolaisen

Trang 28

C++ strings and their C progenitors First, C++ string objects associate the array of

characters which constitute the string with methods useful for managing and operating on it

A string also contains certain “housekeeping” information about the size and storage location

of its data Specifically, a C++ string object knows its starting location in memory, its

content, its length in characters, and the length in characters to which it can grow before the

string object must resize its internal data buffer This gives rise to the second big difference between C char arrays and C++ strings C++ strings do not include a null terminator, nor do the C++ string handling member functions rely on the existence of a null terminator to perform their jobs C++ strings greatly reduce the likelihood of making three of the most

common and destructive C programming errors: overwriting array bounds, trying to access arrays through uninitialized or incorrectly valued pointers, and leaving pointers “dangling” after an array ceases to occupy the storage that was once allocated to it

The exact implementation of memory layout for the string class is not defined by the C++ Standard This architecture is intended to be flexible enough to allow differing

implementations by compiler vendors, yet guarantee predictable behavior for users In particular, the exact conditions under which storage is allocated to hold data for a string object are not defined String allocation rules were formulated to allow but not require a reference-counted implementation, but whether or not the implementation uses reference counting, the

semantics must be the same To put this a bit differently, in C, every char array occupies a unique physical region of memory In C++, individual string objects may or may not occupy

unique physical regions of memory, but if reference counting is used to avoid storing

duplicate copies of data, the individual objects must look and act as though they do

exclusively own unique regions of storage For example:

// This may copy the first to the second or

// use reference counting to simulate a copy

Reference counting may serve to make an implementation more memory efficient, but it is

transparent to users of the string class

Trang 29

Creating and initializing C++ strings

Creating and initializing strings is a straightforward proposition, and fairly flexible as well In the example shown below, the first string, imBlank, is declared but contains no initial value Unlike a C char array, which would contain a random and meaningless bit pattern until initialization, imBlank does contain meaningful information This string object has been

initialized to hold “no characters,” and can properly report its 0 length and absence of data elements through the use of class member functions

The next string, heyMom, is initialized by the literal argument "Where are my socks?" This form of initialization uses a quoted character array as a parameter to the string constructor

By contrast, standardReply is simply initialized with an assignment The last string of the group, useThisOneAgain, is initialized using an existing C++ string object Put another way, this example illustrates that string objects let you:

Create an empty string and defer initializing it with character data

Initialize a string by passing a literal, quoted character array as an argument to the

constructor

Initialize a string using ‘=‘

Use one string to initialize another

string heyMom("Where are my socks?");

string standardReply = "Beamed into deep "

"space on wide angle dispersion?";

string useThisOneAgain(standardReply);

} ///:~

These are the simplest forms of string initialization, but there are other variations which offer

more flexibility and control You can :

Use a portion of either a C char array or a C++ string

Combine different sources of initialization data using operator+

Use the string object’s substr( ) member function to create a substring

//: C01:SmallString2.cpp

#include <string>

#include <iostream>

using namespace std;

Trang 30

int main() {

string s1

("What is the sound of one clam napping?");

string s2

("Anything worth doing is worth overdoing.");

string s3("I saw Elvis in a UFO.");

// Copy the first 8 chars

// Copy all sorts of stuff

string quoteMe = s4 + "that" +

// substr() copies 10 chars at element 20

s1.substr(20, 10) + s5 +

// substr() copies up to either 100 char

// or eos starting at element 5

The string member function substr( ) takes a starting position as its first argument and the

number of characters to select as the second argument Both of these arguments have default

values and if you say substr( ) with an empty argument list you produce a copy of the entire string, so this is a convenient way to duplicate a string

Here’s what the string quoteMe contains after the initialization shown above :

"What is that one clam doing with Elvis in a UFO.?"

Notice the final line of example above C++ allows string initialization techniques to be

mixed in a single statement, a flexible and convenient feature Also note that the last

initializer copies just one character from the source string

Another slightly more subtle initialization technique involves the use of the string iterators

string.begin( ) and string.end( ) This treats a string like a container object (which you’ve

seen primarily in the form of vector so far in this book – you’ll see many more containers

soon) which has iterators indicating the start and end of the “container.” This way you can

hand a string constructor two iterators and it will copy from one to the other into the new string:

//: C01:StringIterators.cpp

Trang 31

If you’ve programmed in C, you are accustomed to the convenience of a large family of

functions for writing, searching, rearranging, and copying char arrays However, there are two unfortunate aspects of the Standard C library functions for handling char arrays First,

there are three loosely organized families of them: the “plain” group, the group that

manipulates the characters without respect to case, and the ones which require you to supply a

count of the number of characters to be considered in the operation at hand The roster of

function names in the C char array handling library literally runs to several pages, and though

the kind and number of arguments to the functions are somewhat consistent within each of the three groups, to use them properly you must be very attentive to details of function naming and parameter passing

Trang 32

The second inherent trap of the standard C char array tools is that they all rely explicitly on

the assumption that the character array includes a null terminator If by oversight or error the

null is omitted or overwritten, there’s very little to keep the C char array handling functions

from manipulating the memory beyond the limits of the allocated space, sometimes with disastrous results

C++ provides a vast improvement in the convenience and safety of string objects For

purposes of actual string handling operations, there are a modest two or three dozen member function names It’s worth your while to become acquainted with these Each function is

overloaded, so you don’t have to learn a new string member function name simply because of

small differences in their parameters

Appending, inserting and concatenating strings

One of the most valuable and convenient aspects of C++ strings is that they grow as needed, without intervention on the part of the programmer Not only does this make string handling code inherently more trustworthy, it also almost entirely eliminates a tedious “housekeeping” chore – keeping track of the bounds of the storage in which your strings live For example, if you create a string object and initialize it with a string of 50 copies of ‘X’, and later store in it

50 copies of “Zowie”, the object itself will reallocate sufficient storage to accommodate the growth of the data Perhaps nowhere is this property more appreciated than when the strings manipulated in your code change in size, and you don’t know how big the change is

Appending, concatenating, and inserting strings often give rise to this circumstance, but the

string member functions append( ) and insert( ) transparently reallocate storage when a string

string bigNews("I saw Elvis in a UFO ");

cout << bigNews << endl;

// How much data have we actually got?

cout << "Size = " << bigNews.size() << endl;

// How much can we store without reallocating

Trang 33

cout << "Size = " << bigNews.size() << endl;

cout << "Capacity = "

<< bigNews.capacity() << endl;

// Make sure that there will be this much space

bigNews.reserve(500);

// Add this to the end of the string

bigNews.append("I've been working too hard.");

cout << bigNews << endl;

cout << "Size = " << bigNews.size() << endl;

cout << "Capacity = "

<< bigNews.capacity() << endl;

} ///:~

Here is the output:

I saw Elvis in a UFO

I thought I saw Elvis in a UFO I've been

working too hard

Size = 66

Capacity = 511

This example demonstrates that even though you can safely relinquish much of the

responsibility for allocating and managing the memory your strings occupy, C++ strings provide you with several tools to monitor and manage their size The size( ), resize( ), capacity( ), and reserve( ) member functions can be very useful when its necessary to work

back and forth between data contained in C++ style strings and traditional null terminated C

char arrays Note the ease with which we changed the size of the storage allocated to the

string

The exact fashion in which the string member functions will allocate space for your data is

dependent on the implementation of the library When one implementation was tested with the example above, it appeared that reallocations occurred on even word boundaries, with one

byte held back The architects of the string class have endeavored to make it possible to mix the use of C char arrays and C++ string objects, so it is likely that figures reported by StrSize.cpp for capacity reflect that in this particular implementation, a byte is set aside to

easily accommodate the insertion of a null terminator

Trang 34

Replacing string characters

insert( ) is particularly nice because it absolves you of making sure the insertion of characters

in a string won’t overrun the storage space or overwrite the characters immediately following the insertion point Space grows and existing characters politely move over to accommodate the new elements Sometimes, however, this might not be what you want to happen If the data in string needs to retain the ordering of the original characters relative to one another or

must be a specific constant size, use the replace( ) function to overwrite a particular sequence

of characters with another group of characters There are quite a number of overloaded

versions of replace( ), but the simplest one takes three arguments: an integer telling where to

start in the string, an integer telling how many characters to eliminate from the original string, and the replacement string (which can be a different number of characters than the eliminated quantity) Here’s a very simple example:

int start = s.find(tag);

cout << "start = " << start << endl;

cout << "size = " << tag.size() << endl;

s.replace(start, tag.size(), "hello there");

cout << s << endl;

} ///:~

The tag is first inserted into s (notice that the insert happens before the value indicating the

insert point, and that an extra space was added after tag), then it is found and replaced You should actually check to see if you’ve found anything before you perform a replace( ) The above example replaces with a char*, but there’s an overloaded version that replaces with a string Here’s a more complete demonstration replace( )

Trang 35

string findMe, string newChars){

// Look in modifyMe for the "find string"

"I thought I saw Elvis in a UFO "

"I have been working too hard.";

string replacement("wig");

string findMe("UFO");

// Find "UFO" in bigNews and overwrite it:

replaceChars(bigNews, findMe, replacement);

cout << bigNews << endl;

} ///:~

Now the last line of output from replace.cpp looks like this:

I thought I saw Elvis in a wig I have been

working too hard

If replace doesn’t find the search string, it returns npos npos is a static constant member of the basic_string class

Unlike insert( ), replace( ) won’t grow the string’s storage space if you copy new characters

into the middle of an existing series of array elements However, it will grow the storage

space if you make a “replacement” that writes beyond the end of an existing array Here’s an example:

string bigNews("I saw Elvis in a UFO "

"I have been working too hard.");

string replacement("wig");

// The first arg says "replace chars

// beyond the end of the existing string":

bigNews.replace(bigNews.size(),

Trang 36

replacement.size(), replacement);

cout << bigNews << endl;

} ///:~

The call to replace( ) begins “replacing” beyond the end of the existing array The output

looks like this:

I saw Elvis in a UFO I have

been working too hard.wig

Notice that replace( ) expands the array to accommodate the growth of the string due to

“replacement” beyond the bounds of the existing array

Simple character replacement using the STL

replace( ) algorithm

You may have been hunting through this chapter trying to do something relatively simple like replace all the instances of one character with a different character Upon finding the above section on replacing, you thought you found the answer but then you started seeing groups of

characters and counts and other things that looked a bit too complex Doesn’t string have a

way to just replace one character with another everywhere?

The string class by itself doesn’t solve all possible problems The remainder are relegated to the STL algorithms, because the string class can look just like an STL container (the STL

algorithms work with anything that looks like an STL container) All the STL algorithms work on a “range” of elements within a container Usually that range is just “from the

beginning of the container to the end.” A string object looks like a container of characters: to get the beginning of the range you use string::begin( ) and to get the end of the range you use string::end( ) The following example shows the use of the STL replace( ) algorithm to

replace all the instances of ‘X’ with ‘Y’:

Notice that this replace( ) is not called as a member function of string Also, unlike the

string::replace( ) functions which only perform one replacement, the STL replace is

replacing all instances of one character with another

Trang 37

The STL replace( ) algorithm only works with single objects (in this case, char objects), and will not perform replacements of quoted char arrays or of string objects

Since a string looks like an STL container, there are a number of other STL algorithms that

can be applied to it, which may solve other problems you have that are not directly addressed

by the string member functions See Chapter XX for more information on the STL

string s3("The other ");

// operator+ concatenates strings

This That The other

This That The other ooh lala

Trang 38

operator+ and operator+= are a very flexible and convenient means of combining string

data On the right hand side of the statement, you can use almost any type that evaluates to a group of one or more characters

Searching in strings

The find family of string member functions allows you to locate a character or group of characters within a given string Here are the members of the find family and their general

usage:

string find member function What/how it finds

group of characters and returns the starting

position of the first occurrence found or npos

if no match is found (npos is a const of –1

and indicates that a search failed.)

position of the first match of any character in

a specified group If no match is found, it

returns npos

position of the last match of any character in

a specified group If no match is found, it

returns npos

find_first_not_of( ) Searches a target string and returns the

position of the first element that doesn’t match any character in a specified group If

no such element is found, it returns npos

position of the element with the largest

subscript that doesn’t match of any character

in a specified group If no such element is

found, it returns npos

specified character or group of characters and returns the starting position of the match if one is found If no match is found, it returns

npos

String searching member functions and their general uses

Trang 39

The simplest use of find( ) searches for one or more characters in a string This overloaded version of find( ) takes a parameter that specifies the character(s) for which to search, and

optionally one that tells it where in the string to begin searching for the occurrence of a

substring (The default position at which to begin searching is 0.) By setting the call to find

inside a loop, you can easily move through a string, repeating a search in order to find all of the occurrences of a given character or group of characters within the string

Notice that we define the string object sieveChars using a constructor idiom which sets the

initial size of the character array and writes the value ‘P’ to each of its member

// Create a 50 char string and set each

// element to 'P' for Prime

string sieveChars(50, 'P');

// By definition neither 0 nor 1 is prime

// Change these elements to "N" for Not Prime

cout << "Prime:" << endl;

// Return the index of the first 'P' element:

cout << "\n Not prime:" << endl;

// Find the first element value not equal P:

Trang 40

This tells us that the first ‘e’ of the search group “een” was found in the word “meenie,” and

is the eighth element in the string Notice that find passed over the “Een” group of characters

in the word “Eenie” The find member function performs a case sensitive search

Ngày đăng: 08/03/2014, 23:20

TỪ KHÓA LIÊN QUAN