The
C+ +
Programming
Language
Third Edition
Bjarne Stroustrup
AT&T Labs
Murray Hill, New Jersey
Addison-Wesley
An Imprint of Addison Wesley Longman, Inc.
Reading, Massachusetts • Harlow, England • Menlo Park, California
Berkeley, California • Don Mills, Ontario • Sydney
Bonn • Amsterdam • Tokyo • Mexico City
ii
Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where
those designations appear in this book, and Addison-Wesley was aware of a trademark claim, the designations have been
printed in initial capital letters or all capital letters
The author and publisher have taken care in the preparation of this book, but make no expressed or implied warranty of any
kind and assume no responsibility for errors or omissions. No liability is assumed for incidental or consequential damages in
connection with or arising out of the use of the information contained herein.
The publisher offers discounts on this book when ordered in quantity for special sales. For more information please contact:
Corporate & Professional Publishing Group
Addison-Wesley Publishing Company
One Jacob Way
Reading, Massachusetts 01867
Library of Congress Cataloging-in-Publication Data
Stroustrup, Bjarne
The C++ Programming Language / Bjarne Stroustrup. — 3rd. ed.
p. cm.
Includes index.
ISBN 0-201-88954-4
1. C++ (Computer Programming Language) I. Title
QA76.73.C153S77 1997 97-20239
005.13’3—dc21 CIP
Copyright © 1997 by AT&T
All rights reserved. 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, or otherwise, without the prior written permission of the
publisher. Printed in the United States of America.
This book was typeset in Times and Courier by the author.
ISBN 0-201-88954-4
Printed on recycled paper
1 2 3 4 5 6 7 8 9—CRW—0100999897
First printing, June 1997
Contents
Contents iii
Preface v
Preface to Second Edition vii
Preface to First Edition ix
Introductory Material 1
1 Notes to the Reader ..................................................................... 3
2 A Tour of C++ ............................................................................. 21
3 A Tour of the Standard Library .................................................. 45
Part I: Basic Facilities 67
4 Types and Declarations ............................................................... 69
5 Pointers, Arrays, and Structures .................................................. 87
6 Expressions and Statements ........................................................ 107
7 Functions ..................................................................................... 143
8 Namespaces and Exceptions ....................................................... 165
9 Source Files and Programs .......................................................... 197
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
iv Contents
Part II: Abstraction Mechanisms 221
10 Classes ........................................................................................ 223
11 Operator Overloading ................................................................. 261
12 Derived Classes ........................................................................... 301
13 Templates .................................................................................... 327
14 Exception Handling .................................................................... 355
15 Class Hierarchies ........................................................................ 389
Part III: The Standard Library 427
16 Library Organization and Containers .......................................... 429
17 Standard Containers .................................................................... 461
18 Algorithms and Function Objects ............................................... 507
19 Iterators and Allocators ............................................................... 549
20 Strings ......................................................................................... 579
21 Streams ........................................................................................ 605
22 Numerics ..................................................................................... 657
Part IV: Design Using C++ 689
23 Development and Design ............................................................ 691
24 Design and Programming ........................................................... 723
25 Roles of Classes .......................................................................... 765
Appendices 791
A The C++ Grammar ...................................................................... 793
B Compatibility .............................................................................. 815
C Technicalities .............................................................................. 827
Index 869
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Preface to the First Edition
Language shapes the way we think,
and determines what we can think about.
– B.L.Whorf
C++ is a general purpose programming language designed to make programming more enjoyable
for the serious programmer. Except for minor details, C++ is a superset of the C programming language.
In addition to the facilities provided by C, C++ provides flexible and efficient facilities for
defining new types. A programmer can partition an application into manageable pieces by defining
new types that closely match the concepts of the application. This technique for program construction
is often called data abstraction. Objects of some user-defined types contain type information.
Such objects can be used conveniently and safely in contexts in which their type cannot be determined
at compile time. Programs using objects of such types are often called object based. When
used well, these techniques result in shorter, easier to understand, and easier to maintain programs.
The key concept in C++ is class. A class is a user-defined type. Classes provide data hiding,
guaranteed initialization of data, implicit type conversion for user-defined types, dynamic typing,
user-controlled memory management, and mechanisms for overloading operators. C++ provides
much better facilities for type checking and for expressing modularity than C does. It also contains
improvements that are not directly related to classes, including symbolic constants, inline substitution
of functions, default function arguments, overloaded function names, free store management
operators, and a reference type. C++ retains C’s ability to deal efficiently with the fundamental
objects of the hardware (bits, bytes, words, addresses, etc.). This allows the user-defined types to
be implemented with a pleasing degree of efficiency.
C++ and its standard libraries are designed for portability. The current implementation will run
on most systems that support C. C libraries can be used from a C++ program, and most tools that
support programming in C can be used with C++.
This book is primarily intended to help serious programmers learn the language and use it for
nontrivial projects. It provides a complete description of C++, many complete examples, and many
more program fragments.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
x Preface to the First Edition
Acknowledgments
C++ could never have matured without the constant use, suggestions, and constructive criticism of
many friends and colleagues. In particular, Tom Cargill, Jim Coplien, Stu Feldman, Sandy Fraser,
Steve Johnson, Brian Kernighan, Bart Locanthi, Doug McIlroy, Dennis Ritchie, Larry Rosler, Jerry
Schwarz, and Jon Shopiro provided important ideas for development of the language. Dave Presotto
wrote the current implementation of the stream I/O library.
In addition, hundreds of people contributed to the development of C++ and its compiler by
sending me suggestions for improvements, descriptions of problems they had encountered, and
compiler errors. I can mention only a few: Gary Bishop, Andrew Hume, Tom Karzes, Victor
Milenkovic, Rob Murray, Leonie Rose, Brian Schmult, and Gary Walker.
Many people have also helped with the production of this book, in particular, Jon Bentley,
Laura Eaves, Brian Kernighan, Ted Kowalski, Steve Mahaney, Jon Shopiro, and the participants in
the C++ course held at Bell Labs, Columbus, Ohio, June 26-27, 1985.
Murray Hill, New Jersey Bjarne Stroustrup
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Preface to the Second Edition
The road goes ever on and on.
– Bilbo Baggins
As promised in the first edition of this book, C++ has been evolving to meet the needs of its users.
This evolution has been guided by the experience of users of widely varying backgrounds working
in a great range of application areas. The C++ user-community has grown a hundredfold during the
six years since the first edition of this book; many lessons have been learned, and many techniques
have been discovered and/or validated by experience. Some of these experiences are reflected here.
The primary aim of the language extensions made in the last six years has been to enhance C++
as a language for data abstraction and object-oriented programming in general and to enhance it as
a tool for writing high-quality libraries of user-defined types in particular. A ‘‘high-quality
library,’’ is a library that provides a concept to a user in the form of one or more classes that are
convenient, safe, and efficient to use. In this context, safe means that a class provides a specific
type-safe interface between the users of the library and its providers; efficient means that use of the
class does not impose significant overheads in run-time or space on the user compared with handwritten
C code.
This book presents the complete C++ language. Chapters 1 through 10 give a tutorial introduction;
Chapters 11 through 13 provide a discussion of design and software development issues; and,
finally, the complete C++ reference manual is included. Naturally, the features added and resolutions
made since the original edition are integral parts of the presentation. They include refined
overloading resolution, memory management facilities, and access control mechanisms, type-safe
linkage, constand staticmember functions, abstract classes, multiple inheritance, templates, and
exception handling.
C++ is a general-purpose programming language; its core application domain is systems programming
in the broadest sense. In addition, C++ is successfully used in many application areas
that are not covered by this label. Implementations of C++ exist from some of the most modest
microcomputers to the largest supercomputers and for almost all operating systems. Consequently,
this book describes the C++ language itself without trying to explain a particular implementation,
programming environment, or library.
This book presents many examples of classes that, though useful, should be classified as
‘‘toys.’’ This style of exposition allows general principles and useful techniques to stand out more
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
viii Preface to the Second Edition
clearly than they would in a fully elaborated program, where they would be buried in details. Most
of the useful classes presented here, such as linked lists, arrays, character strings, matrices, graphics
classes, associative arrays, etc., are available in ‘‘bulletproof’’ and/or ‘‘goldplated’’ versions from a
wide variety of commercial and non-commercial sources. Many of these ‘‘industrial strength’’
classes and libraries are actually direct and indirect descendants of the toy versions found here.
This edition provides a greater emphasis on tutorial aspects than did the first edition of this
book. However, the presentation is still aimed squarely at experienced programmers and endeavors
not to insult their intelligence or experience. The discussion of design issues has been greatly
expanded to reflect the demand for information beyond the description of language features and
their immediate use. Technical detail and precision have also been increased. The reference manual,
in particular, represents many years of work in this direction. The intent has been to provide a
book with a depth sufficient to make more than one reading rewarding to most programmers. In
other words, this book presents the C++ language, its fundamental principles, and the key techniques
needed to apply it. Enjoy!
Acknowledgments
In addition to the people mentioned in the acknowledgements section in the preface to the first edition,
I would like to thank Al Aho, Steve Buroff, Jim Coplien, Ted Goldstein, Tony Hansen, Lorraine
Juhl, Peter Juhl, Brian Kernighan, Andrew Koenig, Bill Leggett, Warren Montgomery, Mike
Mowbray, Rob Murray, Jonathan Shopiro, Mike Vilot, and Peter Weinberger for commenting on
draft chapters of this second edition. Many people influenced the development of C++ from 1985
to 1991. I can mention only a few: Andrew Koenig, Brian Kernighan, Doug McIlroy, and Jonathan
Shopiro. Also thanks to the many participants of the ‘‘external reviews’’ of the reference manual
drafts and to the people who suffered through the first year of X3J16.
Murray Hill, New Jersey Bjarne Stroustrup
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Preface
Programming is understanding.
– Kristen Nygaard
I find using C++ more enjoyable than ever. C++’s support for design and programming has
improved dramatically over the years, and lots of new helpful techniques have been developed for
its use. However, C++ is not just fun. Ordinary practical programmers have achieved significant
improvements in productivity, maintainability, flexibility, and quality in projects of just about any
kind and scale. By now, C++ has fulfilled most of the hopes I originally had for it, and also succeeded
at tasks I hadn’t even dreamt of.
This book introduces standard C++† and the key programming and design techniques supported
by C++. Standard C++ is a far more powerful and polished language than the version of C++ introduced
by the first edition of this book. New language features such as namespaces, exceptions,
templates, and run-time type identification allow many techniques to be applied more directly than
was possible before, and the standard library allows the programmer to start from a much higher
level than the bare language.
About a third of the information in the second edition of this book came from the first. This
third edition is the result of a rewrite of even larger magnitude. It offers something to even the
most experienced C++ programmer; at the same time, this book is easier for the novice to approach
than its predecessors were. The explosion of C++ use and the massive amount of experience accumulated
as a result makes this possible.
The definition of an extensive standard library makes a difference to the way C++ concepts can
be presented. As before, this book presents C++ independently of any particular implementation,
and as before, the tutorial chapters present language constructs and concepts in a ‘‘bottom up’’
order so that a construct is used only after it has been defined. However, it is much easier to use a
well-designed library than it is to understand the details of its implementation. Therefore, the standard
library can be used to provide realistic and interesting examples well before a reader can be
assumed to understand its inner workings. The standard library itself is also a fertile source of programming
examples and design techniques.
__________________
† ISO/IEC 14882, Standard for the C++ Programming Language.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
vi Preface
This book presents every major C++ language feature and the standard library. It is organized
around language and library facilities. However, features are presented in the context of their use.
That is, the focus is on the language as the tool for design and programming rather than on the language
in itself. This book demonstrates key techniques that make C++ effective and teaches the
fundamental concepts necessary for mastery. Except where illustrating technicalities, examples are
taken from the domain of systems software. A companion, The Annotated C++ Language Standard,
presents the complete language definition together with annotations to make it more comprehensible.
The primary aim of this book is to help the reader understand how the facilities offered by C++
support key programming techniques. The aim is to take the reader far beyond the point where he
or she gets code running primarily by copying examples and emulating programming styles from
other languages. Only a good understanding of the ideas behind the language facilities leads to
mastery. Supplemented by implementation documentation, the information provided is sufficient
for completing significant real-world projects. The hope is that this book will help the reader gain
new insights and become a better programmer and designer.
Acknowledgments
In addition to the people mentioned in the acknowledgement sections of the first and second editions,
I would like to thank Matt Austern, Hans Boehm, Don Caldwell, Lawrence Crowl, Alan
Feuer, Andrew Forrest, David Gay, Tim Griffin, Peter Juhl, Brian Kernighan, Andrew Koenig,
Mike Mowbray, Rob Murray, Lee Nackman, Joseph Newcomer, Alex Stepanov, David Vandevoorde,
Peter Weinberger, and Chris Van Wyk for commenting on draft chapters of this third edition.
Without their help and suggestions, this book would have been harder to understand, contained
more errors, been slightly less complete, and probably been a little bit shorter.
I would also like to thank the volunteers on the C++ standards committees who did an immense
amount of constructive work to make C++ what it is today. It is slightly unfair to single out individuals,
but it would be even more unfair not to mention anyone, so I’d like to especially mention
Mike Ball, Dag Br. .
uck, Sean Corfield, Ted Goldstein, Kim Knuttila, Andrew Koenig, José e Lajoie,
Dmitry Lenkov, Nathan Myers, Martin O’Riordan, Tom Plum, Jonathan Shopiro, John Spicer,
Jerry Schwarz, Alex Stepanov, and Mike Vilot, as people who each directly cooperated with me
over some part of C++ and its standard library.
Murray Hill, New Jersey Bjarne Stroustrup
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Introduction
This introduction gives an overview of the major concepts and features of the C++ programming
language and its standard library. It also provides an overview of this book
and explains the approach taken to the description of the language facilities and their
use. In addition, the introductory chapters present some background information about
C++, the design of C++, and the use of C++.
Chapters
1 Notes to the Reader
2 A Tour of C++
3 A Tour of the Standard Library
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
2 Introduction Introduction
‘‘... and you, Marcus, you have given me many things; now I shall give you this good
advice. Be many people. Give up the game of being always Marcus Cocoza. You
have worried too much about Marcus Cocoza, so that you have been really his slave
and prisoner. You have not done anything without first considering how it would
affect Marcus Cocoza’s happiness and prestige. You were always much afraid that
Marcus might do a stupid thing, or be bored. What would it really have mattered? All
over the world people are doing stupid things ... I should like you to be easy, your little
heart to be light again. You must from now, be more than one, many people, as
many as you can think of ...’’
– Karen Blixen
(‘‘The Dreamers’’ from ‘‘Seven Gothic Tales’’
written under the pseudonym Isak Dinesen,
Random House, Inc.
Copyright, Isac Dinesen, 1934 renewed 1961)
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
_ _ _______________________________________________________________________________________________________________________________ _______________________________________ ________________________________
1 _ _ _______________________________________________________________________________________________________________________________ _______________________________________ ________________________________
Notes to the Reader
"The time has come," the Walrus said,
"to talk of many things."
– L.Carroll
Structure of this book — how to learn C++ — the design of C++ — efficiency and structure
— philosophical note — historical note — what C++ is used for — C and C++ —
suggestions for C programmers — suggestions for C++ programmers — thoughts about
programming in C++ — advice — references.
1.1 The Structure of This Book [notes.intro]
This book consists of six parts:
Introduction: Chapters 1 through 3 give an overview of the C++ language, the key programming
styles it supports, and the C++ standard library.
Part I: Chapters 4 through 9 provide a tutorial introduction to C++’s built-in types and the
basic facilities for constructing programs out of them.
Part II: Chapters 10 through 15 are a tutorial introduction to object-oriented and generic programming
using C++.
Part III: Chapters 16 through 22 present the C++ standard library.
Part IV: Chapters 23 through 25 discuss design and software development issues.
Appendices: Appendices A through C provide language-technical details.
Chapter 1 provides an overview of this book, some hints about how to use it, and some background
information about C++ and its use. You are encouraged to skim through it, read what appears interesting,
and return to it after reading other parts of the book.
Chapters 2 and 3 provide an overview of the major concepts and features of the C++ programming
language and its standard library. Their purpose is to motivate you to spend time on fundamental
concepts and basic language features by showing what can be expressed using the complete
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
4 Notes to the Reader Chapter 1
C++ language. If nothing else, these chapters should convince you that C++ isn’t (just) C and that
C++ has come a long way since the first and second editions of this book. Chapter 2 gives a highlevel
acquaintance with C++. The discussion focuses on the language features supporting data
abstraction, object-oriented programming, and generic programming. Chapter 3 introduces the
basic principles and major facilities of the standard library. This allows me to use standard library
facilities in the following chapters. It also allows you to use library facilities in exercises rather
than relying directly on lower-level, built-in features.
The introductory chapters provide an example of a general technique that is applied throughout
this book: to enable a more direct and realistic discussion of some technique or feature, I occasionally
present a concept briefly at first and then discuss it in depth later. This approach allows me to
present concrete examples before a more general treatment of a topic. Thus, the organization of
this book reflects the observation that we usually learn best by progressing from the concrete to the
abstract – even where the abstract seems simple and obvious in retrospect.
Part I describes the subset of C++ that supports the styles of programming traditionally done in
C or Pascal. It covers fundamental types, expressions, and control structures for C++ programs.
Modularity – as supported by namespaces, source files, and exception handling – is also discussed.
I assume that you are familiar with the fundamental programming concepts used in Part I. For
example, I explain C++’s facilities for expressing recursion and iteration, but I do not spend much
time explaining how these concepts are useful.
Part II describes C++’s facilities for defining and using new types. Concrete and abstract
classes (interfaces) are presented here (Chapter 10, Chapter 12), together with operator overloading
(Chapter 11), polymorphism, and the use of class hierarchies (Chapter 12, Chapter 15). Chapter 13
presents templates, that is, C++’s facilities for defining families of types and functions. It demonstrates
the basic techniques used to provide containers, such as lists, and to support generic programming.
Chapter 14 presents exception handling, discusses techniques for error handling, and
presents strategies for fault tolerance. I assume that you either aren’t well acquainted with objectoriented
programming and generic programming or could benefit from an explanation of how the
main abstraction techniques are supported by C++. Thus, I don’t just present the language features
supporting the abstraction techniques; I also explain the techniques themselves. Part IV goes further
in this direction.
Part III presents the C++ standard library. The aim is to provide an understanding of how to use
the library, to demonstrate general design and programming techniques, and to show how to extend
the library. The library provides containers (such as list, vector, and map; Chapter 16, Chapter 17),
standard algorithms (such as sort, find, and merge; Chapter 18, Chapter 19), strings (Chapter 20),
Input/Output (Chapter 21), and support for numerical computation (Chapter 22).
Part IV discusses issues that arise when C++ is used in the design and implementation of large
software systems. Chapter 23 concentrates on design and management issues. Chapter 24 discusses
the relation between the C++ programming language and design issues. Chapter 25 presents some
ways of using classes in design.
Appendix A is C++’s grammar, with a few annotations. Appendix B discusses the relation
between C and C++ and between Standard C++ (also called ISO C++ and ANSI C++) and the versions
of C++ that preceded it. Appendix C presents some language-technical examples.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 1.1.1 Examples and References 5
1.1.1 Examples and References [notes.examples]
This book emphasizes program organization rather than the writing of algorithms. Consequently, I
avoid clever or harder-to-understand algorithms. A trivial algorithm is typically better suited to
illustrate an aspect of the language definition or a point about program structure. For example, I
use a Shell sort where, in real code, a quicksort would be better. Often, reimplementation with a
more suitable algorithm is an exercise. In real code, a call of a library function is typically more
appropriate than the code used here for illustration of language features.
Textbook examples necessarily give a warped view of software development. By clarifying and
simplifying the examples, the complexities that arise from scale disappear. I see no substitute for
writing realistically-sized programs for getting an impression of what programming and a programming
language are really like. This book concentrates on the language features, the basic techniques
from which every program is composed, and the rules for composition.
The selection of examples reflects my background in compilers, foundation libraries, and simulations.
Examples are simplified versions of what is found in real code. The simplification is necessary
to keep programming language and design points from getting lost in details. There are no
‘‘cute’’ examples without counterparts in real code. Wherever possible, I relegated to Appendix C
language-technical examples of the sort that use variables named xand y, types called Aand B, and
functions called f() and g().
In code examples, a proportional-width font is used for identifiers. For example:
#include
int main()
{
std: :cout<< "Hello, new world!\n";
}
At first glance, this presentation style will seem ‘‘unnatural’’ to programmers accustomed to seeing
code in constant-width fonts. However, proportional-width fonts are generally regarded as better
than constant-width fonts for presentation of text. Using a proportional-width font also allows me
to present code with fewer illogical line breaks. Furthermore, my experiments show that most people
find the new style more readable after a short while.
Where possible, the C++ language and library features are presented in the context of their use
rather than in the dry manner of a manual. The language features presented and the detail in which
they are described reflect my view of what is needed for effective use of C++. A companion, The
Annotated C++ Language Standard, authored by Andrew Koenig and myself, is the complete definition
of the language together with comments aimed at making it more accessible. Logically,
there ought to be another companion, The Annotated C++ Standard Library. However, since both
time and my capacity for writing are limited, I cannot promise to produce that.
References to parts of this book are of the form §2.3.4 (Chapter 2, section 3, subsection 4),
§B.5.6 (Appendix B, subsection 5.6), and §6.6[10] (Chapter 6, exercise 10). Italics are used sparingly
for emphasis (e.g., ‘‘a string literal is not acceptable’’), for first occurrences of important concepts
(e.g., polymorphism), for nonterminals of the C++ grammar (e.g., for-statement), and for
comments in code examples. Semi-bold italics are used to refer to identifiers, keywords, and
numeric values from code examples (e.g., class, counter, and 1712).
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
6 Notes to the Reader Chapter 1
1.1.2 Exercises [notes.exercises]
Exercises are found at the ends of chapters. The exercises are mainly of the write-a-program variety.
Always write enough code for a solution to be compiled and run with at least a few test cases.
The exercises vary considerably in difficulty, so they are marked with an estimate of their difficulty.
The scale is exponential so that if a (∗1) exercise takes you ten minutes, a (∗2) might take an
hour, and a (∗3) might take a day. The time needed to write and test a program depends more on
your experience than on the exercise itself. A (∗1) exercise might take a day if you first have to get
acquainted with a new computer system in order to run it. On the other hand, a (∗5) exercise might
be done in an hour by someone who happens to have the right collection of programs handy.
Any book on programming in C can be used as a source of extra exercises for Part I. Any book
on data structures and algorithms can be used as a source of exercises for Parts II and III.
1.1.3 Implementation Note [notes.implementation]
The language used in this book is ‘‘pure C++’’ as defined in the C++ standard [C++,1997]. Therefore,
the examples ought to run on every C++ implementation. The major program fragments in
this book were tried using several C++ implementations. Examples using features only recently
adopted into C++ didn’t compile on every implementation. However, I see no point in mentioning
which implementations failed to compile which examples. Such information would soon be out of
date because implementers are working hard to ensure that their implementations correctly accept
every C++ feature. See Appendix B for suggestions on how to cope with older C++ compilers and
with code written for C compilers.
1.2 Learning C++ [notes.learn]
The most important thing to do when learning C++ is to focus on concepts and not get lost in
language-technical details. The purpose of learning a programming language is to become a better
programmer; that is, to become more effective at designing and implementing new systems and at
maintaining old ones. For this, an appreciation of programming and design techniques is far more
important than an understanding of details; that understanding comes with time and practice.
C++ supports a variety of programming styles. All are based on strong static type checking, and
most aim at achieving a high level of abstraction and a direct representation of the programmer’s
ideas. Each style can achieve its aims effectively while maintaining run-time and space efficiency.
A programmer coming from a different language (say C, Fortran, Smalltalk, Lisp, ML, Ada, Eiffel,
Pascal, or Modula-2) should realize that to gain the benefits of C++, they must spend time learning
and internalizing programming styles and techniques suitable to C++. The same applies to programmers
used to an earlier and less expressive version of C++.
Thoughtlessly applying techniques effective in one language to another typically leads to awkward,
poorly performing, and hard-to-maintain code. Such code is also most frustrating to write
because every line of code and every compiler error message reminds the programmer that the language
used differs from ‘‘the old language.’’ You can write in the style of Fortran, C, Smalltalk,
etc., in any language, but doing so is neither pleasant nor economical in a language with a different
philosophy. Every language can be a fertile source of ideas of how to write C++ programs.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 1.2 Learning C++ 7
However, ideas must be transformed into something that fits with the general structure and type
system of C++ in order to be effective in the different context. Over the basic type system of a language,
only Pyrrhic victories are possible.
C++ supports a gradual approach to learning. How you approach learning a new programming
language depends on what you already know and what you aim to learn. There is no one approach
that suits everyone. My assumption is that you are learning C++ to become a better programmer
and designer. That is, I assume that your purpose in learning C++ is not simply to learn a new syntax
for doing things the way you used to, but to learn new and better ways of building systems.
This has to be done gradually because acquiring any significant new skill takes time and requires
practice. Consider how long it would take to learn a new natural language well or to learn to play a
new musical instrument well. Becoming a better system designer is easier and faster, but not as
much easier and faster as most people would like it to be.
It follows that you will be using C++ – often for building real systems – before understanding
every language feature and technique. By supporting several programming paradigms (Chapter 2),
C++ supports productive programming at several levels of expertise. Each new style of programming
adds another tool to your toolbox, but each is effective on its own and each adds to your
effectiveness as a programmer. C++ is organized so that you can learn its concepts in a roughly linear
order and gain practical benefits along the way. This is important because it allows you to gain
benefits roughly in proportion to the effort expended.
In the continuing debate on whether one needs to learn C before C++, I am firmly convinced
that it is best to go directly to C++. C++ is safer, more expressive, and reduces the need to focus on
low-level techniques. It is easier for you to learn the trickier parts of C that are needed to compensate
for its lack of higher-level facilities after you have been exposed to the common subset of C
and C++ and to some of the higher-level techniques supported directly in C++. Appendix B is a
guide for programmers going from C++ to C, say, to deal with legacy code.
Several independently developed and distributed implementations of C++ exist. A wealth of
tools, libraries, and software development environments are also available. A mass of textbooks,
manuals, journals, newsletters, electronic bulletin boards, mailing lists, conferences, and courses
are available to inform you about the latest developments in C++, its use, tools, libraries, implementations,
etc. If you plan to use C++ seriously, I strongly suggest that you gain access to such
sources. Each has its own emphasis and bias, so use at least two. For example, see [Barton,1994],
[Booch,1994], [Henricson,1997], [Koenig,1997], [Martin,1995].
1.3 The Design of C++ [notes.design]
Simplicity was an important design criterion: where there was a choice between simplifying the
language definition and simplifying the compiler, the former was chosen. However, great importance
was attached to retaining compatibility with C; this precluded cleaning up the C syntax.
C++ has no built-in high-level data types and no high-level primitive operations. For example,
the C++ language does not provide a matrix type with an inversion operator or a string type with a
concatenation operator. If a user wants such a type, it can be defined in the language itself. In fact,
defining a new general-purpose or application-specific type is the most fundamental programming
activity in C++. A well-designed user-defined type differs from a built-in type only in the way it is
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
8 Notes to the Reader Chapter 1
defined, not in the way it is used. The C++ standard library described in Part III provides many
examples of such types and their uses. From a user’s point of view, there is little difference
between a built-in type and a type provided by the standard library.
Features that would incur run-time or memory overheads even when not used were avoided in
the design of C++. For example, constructs that would make it necessary to store ‘‘housekeeping
information’’ in every object were rejected, so if a user declares a structure consisting of two 16-bit
quantities, that structure will fit into a 32-bit register.
C++ was designed to be used in a traditional compilation and run-time environment, that is, the
C programming environment on the UNIX system. Fortunately, C++ was never restricted to UNIX;
it simply used UNIX and C as a model for the relationships between language, libraries, compilers,
linkers, execution environments, etc. That minimal model helped C++ to be successful on essentially
every computing platform. There are, however, good reasons for using C++ in environments
that provide significantly more support. Facilities such as dynamic loading, incremental compilation,
and a database of type definitions can be put to good use without affecting the language.
C++ type-checking and data-hiding features rely on compile-time analysis of programs to prevent
accidental corruption of data. They do not provide secrecy or protection against someone who
is deliberately breaking the rules. They can, however, be used freely without incurring run-time or
space overheads. The idea is that to be useful, a language feature must not only be elegant; it must
also be affordable in the context of a real program.
For a systematic and detailed description of the design of C++, see [Stroustrup,1994].
1.3.1 Efficiency and Structure [notes.efficiency]
C++ was developed from the C programming language and, with few exceptions, retains C as a
subset. The base language, the C subset of C++, is designed so that there is a very close correspondence
between its types, operators, and statements and the objects that computers deal with
directly: numbers, characters, and addresses. Except for the new, delete, typeid, dynamic_cast,
and throwoperators and the try-block, individual C++ expressions and statements need no run-time
support.
C++ can use the same function call and return sequences as C – or more efficient ones. When
even such relatively efficient mechanisms are too expensive, a C++ function can be substituted
inline, so that we can enjoy the notational convenience of functions without run-time overhead.
One of the original aims for C was to replace assembly coding for the most demanding systems
programming tasks. When C++ was designed, care was taken not to compromise the gains in this
area. The difference between C and C++ is primarily in the degree of emphasis on types and structure.
C is expressive and permissive. C++ is even more expressive. However, to gain that increase
in expressiveness, you must pay more attention to the types of objects. Knowing the types of
objects, the compiler can deal correctly with expressions when you would otherwise have had to
specify operations in painful detail. Knowing the types of objects also enables the compiler to
detect errors that would otherwise persist until testing – or even later. Note that using the type system
to check function arguments, to protect data from accidental corruption, to provide new types,
to provide new operators, etc., does not increase run-time or space overheads in C++.
The emphasis on structure in C++ reflects the increase in the scale of programs written since C
was designed. You can make a small program (say, 1,000 lines) work through brute force even
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 1.3.1 Efficiency and Structure 9
when breaking every rule of good style. For a larger program, this is simply not so. If the structure
of a 100,000-line program is bad, you will find that new errors are introduced as fast as old ones are
removed. C++ was designed to enable larger programs to be structured in a rational way so that it
would be reasonable for a single person to cope with far larger amounts of code. In addition, the
aim was to have an average line of C++ code express much more than the average line of C or Pascal
code. C++ has by now been shown to over-fulfill these goals.
Not every piece of code can be well-structured, hardware-independent, easy-to-read, etc. C++
possesses features that are intended for manipulating hardware facilities in a direct and efficient
way without regard for safety or ease of comprehension. It also possesses facilities for hiding such
code behind elegant and safe interfaces.
Naturally, the use of C++ for larger programs leads to the use of C++ by groups of programmers.
C++’s emphasis on modularity, strongly typed interfaces, and flexibility pays off here. C++
has as good a balance of facilities for writing large programs as any language has. However, as
programs get larger, the problems associated with their development and maintenance shift from
being language problems to more global problems of tools and management. Part IV explores
some of these issues.
This book emphasizes techniques for providing general-purpose facilities, generally useful
types, libraries, etc. These techniques will serve programmers of small programs as well as programmers
of large ones. Furthermore, because all nontrivial programs consist of many semiindependent
parts, the techniques for writing such parts serve programmers of all applications.
You might suspect that specifying a program by using a more detailed type structure would lead
to a larger program source text. With C++, this is not so. A C++ program declaring function argument
types, using classes, etc., is typically a bit shorter than the equivalent C program not using
these facilities. Where libraries are used, a C++ program will appear much shorter than its C equivalent,
assuming, of course, that a functioning C equivalent could have been built.
1.3.2 Philosophical Note [notes.philosophy]
A programming language serves two related purposes: it provides a vehicle for the programmer to
specify actions to be executed, and it provides a set of concepts for the programmer to use when
thinking about what can be done. The first purpose ideally requires a language that is ‘‘close to the
machine’’ so that all important aspects of a machine are handled simply and efficiently in a way
that is reasonably obvious to the programmer. The C language was primarily designed with this in
mind. The second purpose ideally requires a language that is ‘‘close to the problem to be solved’’
so that the concepts of a solution can be expressed directly and concisely. The facilities added to C
to create C++ were primarily designed with this in mind.
The connection between the language in which we think/program and the problems and solutions
we can imagine is very close. For this reason, restricting language features with the intent of
eliminating programmer errors is at best dangerous. As with natural languages, there are great benefits
from being at least bilingual. A language provides a programmer with a set of conceptual
tools; if these are inadequate for a task, they will simply be ignored. Good design and the absence
of errors cannot be guaranteed merely by the presence or the absence of specific language features.
The type system should be especially helpful for nontrivial tasks. The C++ class concept has, in
fact, proven itself to be a powerful conceptual tool.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
10 Notes to the Reader Chapter 1
1.4 Historical Note [notes.historical]
I invented C++, wrote its early definitions, and produced its first implementation. I chose and formulated
the design criteria for C++, designed all its major facilities, and was responsible for the
processing of extension proposals in the C++ standards committee.
Clearly, C++ owes much to C [Kernighan,1978]. C is retained as a subset. I also retained C’s
emphasis on facilities that are low-level enough to cope with the most demanding systems programming
tasks. C in turn owes much to its predecessor BCPL [Richards,1980]; in fact, BCPL’s
/ / comment convention was (re)introduced in C++. The other main source of inspiration for C++
was Simula67 [Dahl,1970] [Dahl,1972]; the class concept (with derived classes and virtual functions)
was borrowed from it. C++’s facility for overloading operators and the freedom to place a
declaration wherever a statement can occur resembles Algol68 [Woodward,1974].
Since the original edition of this book, the language has been extensively reviewed and refined.
The major areas for revision were overload resolution, linking, and memory management facilities.
In addition, several minor changes were made to increase C compatibility. Several generalizations
and a few major extensions were added: these included multiple inheritance, staticmember functions,
constmember functions, protectedmembers, templates, exception handling, run-time type
identification, and namespaces. The overall theme of these extensions and revisions was to make
C++ a better language for writing and using libraries. The evolution of C++ is described in [Stroustrup,1994].
The template facility was primarily designed to support statically typed containers (such as lists,
vectors, and maps) and to support elegant and efficient use of such containers (generic programming).
A key aim was to reduce the use of macros and casts (explicit type conversion). Templates
were partly inspired by Ada’s generics (both their strengths and their weaknesses) and partly by
Clu’s parameterized modules. Similarly, the C++ exception-handling mechanism was inspired
partly by Ada [Ichbiah,1979], Clu [Liskov,1979], and ML [Wikströ m,1987]. Other developments
in the 1985 to 1995 time span – such as multiple inheritance, pure virtual functions, and namespaces
– were primarily generalizations driven by experience with the use of C++ rather than ideas
imported from other languages.
Earlier versions of the language, collectively known as ‘‘C with Classes’’ [Stroustrup,1994],
have been in use since 1980. The language was originally invented because I wanted to write some
event-driven simulations for which Simula67 would have been ideal, except for efficiency considerations.
‘‘C with Classes’’ was used for major projects in which the facilities for writing programs
that use minimal time and space were severely tested. It lacked operator overloading, references,
virtual functions, templates, exceptions, and many details. The first use of C++ outside a research
organization started in July 1983.
The name C++ (pronounced ‘‘see plus plus’’) was coined by Rick Mascitti in the summer of
1983. The name signifies the evolutionary nature of the changes from C; ‘‘++’’ is the C increment
operator. The slightly shorter name ‘‘C+’’ is a syntax error; it has also been used as the name of an
unrelated language. Connoisseurs of C semantics find C++ inferior to ++C. The language is not
called D, because it is an extension of C, and it does not attempt to remedy problems by removing
features. For yet another interpretation of the name C++, see the appendix of [Orwell,1949].
C++ was designed primarily so that my friends and I would not have to program in assembler,
C, or various modern high-level languages. Its main purpose was to make writing good programs
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 1.4 Historical Note 11
easier and more pleasant for the individual programmer. In the early years, there was no C++ paper
design; design, documentation, and implementation went on simultaneously. There was no ‘‘C++
project’’ either, or a ‘‘C++ design committee.’’ Throughout, C++ evolved to cope with problems
encountered by users and as a result of discussions between my friends, my colleagues, and me.
Later, the explosive growth of C++ use caused some changes. Sometime during 1987, it
became clear that formal standardization of C++ was inevitable and that we needed to start preparing
the ground for a standardization effort [Stroustrup,1994]. The result was a conscious effort to
maintain contact between implementers of C++ compilers and major users through paper and electronic
mail and through face-to-face meetings at C++ conferences and elsewhere.
AT&T Bell Laboratories made a major contribution to this by allowing me to share drafts of
revised versions of the C++ reference manual with implementers and users. Because many of these
people work for companies that could be seen as competing with AT&T, the significance of this
contribution should not be underestimated. A less enlightened company could have caused major
problems of language fragmentation simply by doing nothing. As it happened, about a hundred
individuals from dozens of organizations read and commented on what became the generally
accepted reference manual and the base document for the ANSI C++ standardization effort. Their
names can be found in The Annotated C++ Reference Manual [Ellis,1989]. Finally, the X3J16
committee of ANSI was convened in December 1989 at the initiative of Hewlett-Packard. In June
1991, this ANSI (American national) standardization of C++ became part of an ISO (international)
standardization effort for C++. From 1990, these joint C++ standards committees have been the
main forum for the evolution of C++ and the refinement of its definition. I served on these committees
throughout. In particular, as the chairman of the working group for extensions, I was directly
responsible for the handling of proposals for major changes to C++ and the addition of new language
features. An initial draft standard for public review was produced in April 1995. A formally
approved international C++ standard is expected in 1998.
C++ evolved hand-in-hand with some of the key classes presented in this book. For example, I
designed complex, vector, and stack classes together with the operator overloading mechanisms.
String and list classes were developed by Jonathan Shopiro and me as part of the same effort.
Jonathan’s string and list classes were the first to see extensive use as part of a library. The string
class from the standard C++ library has its roots in these early efforts. The task library described in
[Stroustrup,1987] and in §12.7[11] was part of the first ‘‘C with Classes’’ program ever written. I
wrote it and its associated classes to support Simula-style simulations. The task library has been
revised and reimplemented, notably by Jonathan Shopiro, and is still in extensive use. The stream
library as described in the first edition of this book was designed and implemented by me. Jerry
Schwarz transformed it into the iostreams library (Chapter 21) using Andrew Koenig’s manipulator
technique (§21.4.6) and other ideas. The iostreams library was further refined during standardization,
when the bulk of the work was done by Jerry Schwarz, Nathan Myers, and Norihiro Kumagai.
The development of the template facility was influenced by the vector, map, list, and sorttemplates
devised by Andrew Koenig, Alex Stepanov, me, and others. In turn, Alex Stepanov’s work
on generic programming using templates led to the containers and algorithms parts of the standard
C++ library (§16.3, Chapter 17, Chapter 18, §19.2). The valarraylibrary for numerical computation
(Chapter 22) is primarily the work of Kent Budge.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
12 Notes to the Reader Chapter 1
1.5 Use of C++ [notes.use]
C++ is used by hundreds of thousands of programmers in essentially every application domain.
This use is supported by about a dozen independent implementations, hundreds of libraries, hundreds
of textbooks, several technical journals, many conferences, and innumerable consultants.
Training and education at a variety of levels are widely available.
Early applications tended to have a strong systems programming flavor. For example, several
major operating systems have been written in C++ [Campbell,1987] [Rozier,1988] [Hamilton,1993]
[Berg,1995] [Parrington,1995] and many more have key parts done in C++. I considered uncompromising
low-level efficiency essential for C++. This allows us to use C++ to write device drivers
and other software that rely on direct manipulation of hardware under real-time constraints. In such
code, predictability of performance is at least as important as raw speed. Often, so is compactness
of the resulting system. C++ was designed so that every language feature is usable in code under
severe time and space constraints [Stroustrup,1994,§4.5].
Most applications have sections of code that are critical for acceptable performance. However,
the largest amount of code is not in such sections. For most code, maintainability, ease of extension,
and ease of testing is key. C++’s support for these concerns has led to its widespread use
where reliability is a must and in areas where requirements change significantly over time. Examples
are banking, trading, insurance, telecommunications, and military applications. For years, the
central control of the U.S. long-distance telephone system has relied on C++ and every 800 call
(that is, a call paid for by the called party) has been routed by a C++ program [Kamath,1993].
Many such applications are large and long-lived. As a result, stability, compatibility, and scalability
have been constant concerns in the development of C++. Million-line C++ programs are not
uncommon.
Like C, C++ wasn’t specifically designed with numerical computation in mind. However, much
numerical, scientific, and engineering computation is done in C++. A major reason for this is that
traditional numerical work must often be combined with graphics and with computations relying on
data structures that don’t fit into the traditional Fortran mold [Budge,1992] [Barton,1994]. Graphics
and user interfaces are areas in which C++ is heavily used. Anyone who has used either an
Apple Macintosh or a PC running Windows has indirectly used C++ because the primary user interfaces
of these systems are C++ programs. In addition, some of the most popular libraries supporting
X for UNIX are written in C++. Thus, C++ is a common choice for the vast number of applications
in which the user interface is a major part.
All of this points to what may be C++’s greatest strength: its ability to be used effectively for
applications that require work in a variety of application areas. It is quite common to find an application
that involves local and wide-area networking, numerics, graphics, user interaction, and database
access. Traditionally, such application areas have been considered distinct, and they have
most often been served by distinct technical communities using a variety of programming languages.
However, C++ has been widely used in all of those areas. Furthermore, it is able to coexist
with code fragments and programs written in other languages.
C++ is widely used for teaching and research. This has surprised some who – correctly – point
out that C++ isn’t the smallest or cleanest language ever designed. It is, however
– clean enough for successful teaching of basic concepts,
– realistic, efficient, and flexible enough for demanding projects,
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 1.5 Use of C++ 13
– available enough for organizations and collaborations relying on diverse development and
execution environments,
– comprehensive enough to be a vehicle for teaching advanced concepts and techniques, and
– commercial enough to be a vehicle for putting what is learned into non-academic use.
C++ is a language that you can grow with.
1.6 C and C++ [notes.c]
C was chosen as the base language for C++ because it
[1] is versatile, terse, and relatively low-level;
[2] is adequate for most systems programming tasks;
[3] runs everywhere and on everything; and
[4] fits into the UNIX programming environment.
C has its problems, but a language designed from scratch would have some too, and we know C’s
problems. Importantly, working with C enabled ‘‘C with Classes’’ to be a useful (if awkward) tool
within months of the first thought of adding Simula-like classes to C.
As C++ became more widely used, and as the facilities it provided over and above those of C
became more significant, the question of whether to retain compatibility was raised again and
again. Clearly some problems could be avoided if some of the C heritage was rejected (see, e.g.,
[Sethi,1981]). This was not done because
[1] there are millions of lines of C code that might benefit from C++, provided that a complete
rewrite from C to C++ were unnecessary;
[2] there are millions of lines of library functions and utility software code written in C that
could be used from/on C++ programs provided C++ were link-compatible with and syntactically
very similar to C;
[3] there are hundreds of thousands of programmers who know C and therefore need only learn
to use the new features of C++ and not relearn the basics; and
[4] C++ and C will be used on the same systems by the same people for years, so the differences
should be either very large or very small so as to minimize mistakes and confusion.
The definition of C++ has been revised to ensure that a construct that is both legal C and legal C++
has the same meaning in both languages (§B.2).
The C language has itself evolved, partly under the influence of the development of C++
[Rosler,1984]. The ANSI C standard [C,1990] contains a function declaration syntax borrowed
from ‘‘C with Classes.’’ Borrowing works both ways. For example, the void* pointer type was
invented for ANSI C and first implemented in C++. As promised in the first edition of this book,
the definition of C++ has been reviewed to remove gratuitous incompatibilities; C++ is now more
compatible with C than it was originally. The ideal was for C++ to be as close to ANSI C as possible
– but no closer [Koenig,1989]. One hundred percent compatibility was never a goal because
that would compromise type safety and the smooth integration of user-defined and built-in types.
Knowing C is not a prerequisite for learning C++. Programming in C encourages many techniques
and tricks that are rendered unnecessary by C++ language features. For example, explicit
type conversion (casting) is less frequently needed in C++ than it is in C (§1.6.1). However, good
C programs tend to be C++ programs. For example, every program in Kernighan and Ritchie, The
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
14 Notes to the Reader Chapter 1
C Programming Language (2nd Edition) [Kernighan,1988], is a C++ program. Experience with
any statically typed language will be a help when learning C++.
1.6.1 Suggestions for C Programmers [notes.suggest]
The better one knows C, the harder it seems to be to avoid writing C++ in C style, thereby losing
some of the potential benefits of C++. Please take a look at Appendix B, which describes the differences
between C and C++. Here are a few pointers to the areas in which C++ has better ways of
doing something than C has:
[1] Macros are almost never necessary in C++. Use const(§5.4) or enum(§4.8) to define manifest
constants, inline(§7.1.1) to avoid function-calling overhead, templates (Chapter 13) to
specify families of functions and types, and namespaces (§8.2) to avoid name clashes.
[2] Don’t declare a variable before you need it so that you can initialize it immediately. A
declaration can occur anywhere a statement can (§6.3.1), in for-statement initializers
(§6.3.3), and in conditions (§6.3.2.1).
[3] Don’t use malloc(). The newoperator (§6.2.6) does the same job better, and instead of
realloc(), try a vector(§3.8).
[4] Try to avoid void*, pointer arithmetic, unions, and casts, except deep within the implementation
of some function or class. In most cases, a cast is an indication of a design error. If
you must use an explicit type conversion, try using one of the ‘‘new casts’’ (§6.2.7) for a
more precise statement of what you are trying to do.
[5] Minimize the use of arrays and C-style strings. The C++ standard library string(§3.5) and
vector(§3.7.1) classes can often be used to simplify programming compared to traditional C
style. In general, try not to build yourself what has already been provided by the standard
library.
To obey C linkage conventions, a C++ function must be declared to have C linkage (§9.2.4).
Most important, try thinking of a program as a set of interacting concepts represented as classes
and objects, instead of as a bunch of data structures with functions twiddling their bits.
1.6.2 Suggestions for C++ Programmers [notes.suggestions]
By now, many people have been using C++ for a decade. Many more are using C++ in a single
environment and have learned to live with the restrictions imposed by early compilers and firstgeneration
libraries. Often, what an experienced C++ programmer has failed to notice over the
years is not the introduction of new features as such, but rather the changes in relationships between
features that make fundamental new programming techniques feasible. In other words, what you
didn’t think of when first learning C++ or found impractical just might be a superior approach
today. You find out only by re-examining the basics.
Read through the chapters in order. If you already know the contents of a chapter, you can be
through in minutes. If you don’t already know the contents, you’ll have learned something unexpected.
I learned a fair bit writing this book, and I suspect that hardly any C++ programmer knows
every feature and technique presented. Furthermore, to use the language well, you need a perspective
that brings order to the set of features and techniques. Through its organization and examples,
this book offers such a perspective.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 1.7 Thinking about Programming in C++ 15
1.7 Thinking about Programming in C++ [notes.thinking]
Ideally, you approach the task of designing a program in three stages. First, you gain a clear understanding
of the problem (analysis), then you identify the key concepts involved in a solution
(design), and finally you express that solution in a program (programming). However, the details
of the problem and the concepts of the solution often become clearly understood only through the
effort to express them in a program and trying to get it to run acceptably. This is where the choice
of programming language matters.
In most applications, there are concepts that are not easily represented as one of the fundamental
types or as a function without associated data. Given such a concept, declare a class to represent it
in the program. A C++ class is a type. That is, it specifies how objects of its class behave: how they
are created, how they can be manipulated, and how they are destroyed. A class may also specify
how objects are represented, although in the early stages of the design of a program that should not
be the major concern. The key to writing good programs is to design classes so that each cleanly
represents a single concept. Often, this means that you must focus on questions such as: How are
objects of this class created? Can objects of this class be copied and/or destroyed? What operations
can be applied to such objects? If there are no good answers to such questions, the concept
probably wasn’t ‘‘clean’’ in the first place. It might then be a good idea to think more about the
problem and its proposed solution instead of immediately starting to ‘‘code around’’ the problems.
The concepts that are easiest to deal with are the ones that have a traditional mathematical formalism:
numbers of all sorts, sets, geometric shapes, etc. Text-oriented I/O, strings, basic containers,
the fundamental algorithms on such containers, and some mathematical classes are part of the
standard C++ library (Chapter 3, §16.1.2). In addition, a bewildering variety of libraries supporting
general and domain-specific concepts are available.
A concept does not exist in a vacuum; there are always clusters of related concepts. Organizing
the relationship between classes in a program – that is, determining the exact relationship between
the different concepts involved in a solution – is often harder than laying out the individual classes
in the first place. The result had better not be a muddle in which every class (concept) depends on
every other. Consider two classes, A and B. Relationships such as ‘‘A calls functions from B,’’
‘‘A creates Bs,’’ and ‘‘A has a B member’’ seldom cause major problems, while relationships such
as ‘‘A uses data from B’’ can typically be eliminated.
One of the most powerful intellectual tools for managing complexity is hierarchical ordering,
that is, organizing related concepts into a tree structure with the most general concept as the root.
In C++, derived classes represent such structures. A program can often be organized as a set of
trees or directed acyclic graphs of classes. That is, the programmer specifies a number of base
classes, each with its own set of derived classes. Virtual functions (§2.5.5, §12.2.6) can often be
used to define operations for the most general version of a concept (a base class). When necessary,
the interpretation of these operations can be refined for particular special cases (derived classes).
Sometimes even a directed acyclic graph seems insufficient for organizing the concepts of a
program; some concepts seem to be inherently mutually dependent. In that case, we try to localize
cyclic dependencies so that they do not affect the overall structure of the program. If you cannot
eliminate or localize such mutual dependencies, then you are most likely in a predicament that no
programming language can help you out of. Unless you can conceive of some easily stated relationships
between the basic concepts, the program is likely to become unmanageable.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
16 Notes to the Reader Chapter 1
One of the best tools for untangling dependency graphs is the clean separation of interface and
implementation. Abstract classes (§2.5.4, §12.3) are C++’s primary tool for doing that.
Another form of commonality can be expressed through templates (§2.7, Chapter 13). A class
template specifies a family of classes. For example, a list template specifies ‘‘list of T,’’ where
‘‘T’’ can be any type. Thus, a template is a mechanism for specifying how one type is generated
given another type as an argument. The most common templates are container classes such as lists,
arrays, and associative arrays and the fundamental algorithms using such containers. It is usually a
mistake to express parameterization of a class and its associated functions with a type using inheritance.
It is best done using templates.
Remember that much programming can be simply and clearly done using only primitive types,
data structures, plain functions, and a few library classes. The whole apparatus involved in defining
new types should not be used except when there is a real need.
The question ‘‘How does one write good programs in C++?’’ is very similar to the question
‘‘How does one write good English prose?’’ There are two answers: ‘‘Know what you want to
say’’ and ‘‘Practice. Imitate good writing.’’ Both appear to be as appropriate for C++ as they are
for English – and as hard to follow.
1.8 Advice [notes.advice]
Here is a set of ‘‘rules’’ you might consider while learning C++. As you get more proficient you
can evolve them into something suitable for your kind of applications and your style of programming.
They are deliberately very simple, so they lack detail. Don’t take them too literally. To
write a good program takes intelligence, taste, and patience. You are not going to get it right the
first time. Experiment!
[1] When you program, you create a concrete representation of the ideas in your solution to some
problem. Let the structure of the program reflect those ideas as directly as possible:
[a] If you can think of ‘‘it’’ as a separate idea, make it a class.
[b] If you can think of ‘‘it’’ as a separate entity, make it an object of some class.
[c] If two classes have a common interface, make that interface an abstract class.
[d] If the implementations of two classes have something significant in common, make that
commonality a base class.
[e] If a class is a container of objects, make it a template.
[f] If a function implements an algorithm for a container, make it a template function implementing
the algorithm for a family of containers.
[g] If a set of classes, templates, etc., are logically related, place them in a common namespace.
[2] When you define either a class that does not implement a mathematical entity like a matrix or a
complex number or a low-level type such as a linked list:
[a] Don’t use global data (use members).
[b] Don’t use global functions.
[c] Don’t use public data members.
[d] Don’t use friends, except to avoid [a] or [c].
[e] Don’t put a ‘‘type field’’ in a class; use virtual functions.
[f] Don’t use inline functions, except as a significant optimization.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 1.8 Advice 17
More specific or detailed rules of thumb can be found in the ‘‘Advice’’ section of each chapter.
Remember, this advice is only rough rules of thumb, not immutable laws. A piece of advice should
be applied only ‘‘where reasonable.’’ There is no substitute for intelligence, experience, common
sense, and good taste.
I find rules of the form ‘‘never do this’’ unhelpful. Consequently, most advice is phrased as
suggestions of what to do, while negative suggestions tend not to be phrased as absolute prohibitions.
I know of no major feature of C++ that I have not seen put to good use. The ‘‘Advice’’ sections
do not contain explanations. Instead, each piece of advice is accompanied by a reference to
the appropriate section of the book. Where negative advice is given, that section usually provides a
suggested alternative.
1.8.1 References [notes.ref]
There are few direct references in the text, but here is a short list of books and papers that are mentioned
directly or indirectly.
[Barton,1994] John J. Barton and Lee R. Nackman: Scientific and Engineering C++.
Addison-Wesley. Reading, Mass. 1994. ISBN 1-201-53393-6.
[Berg,1995] William Berg, Marshall Cline, and Mike Girou: Lessons Learned from the
OS/400 OO Project. CACM. Vol. 38 No. 10. October 1995.
[Booch,1994] Grady Booch: Object-Oriented Analysis and Design. Benjamin/Cummings.
Menlo Park, Calif. 1994. ISBN 0-8053-5340-2.
[Budge,1992] Kent Budge, J. S. Perry, and A. C. Robinson: High-Performance Scientific
Computation using C++. Proc. USENIX C++ Conference. Portland, Oregon.
August 1992.
[C,1990] X3 Secretariat: Standard – The C Language. X3J11/90-013. ISO Standard
ISO/IEC 9899. Computer and Business Equipment Manufacturers Association.
Washington, DC, USA.
[C++,1997] X3 Secretariat: Draft Standard – The C++ Language. X3J16/97-14882. Information
Technology Council (NSITC). Washington, DC, USA.
[Campbell,1987] Roy Campbell, et al.: The Design of a Multiprocessor Operating System. Proc.
USENIX C++ Conference. Santa Fe, New Mexico. November 1987.
[Coplien,1995] James O. Coplien and Douglas C. Schmidt (editors): Pattern Languages of
Program Design. Addison-Wesley. Reading, Mass. 1995. ISBN 1-201-
60734-4.
[Dahl,1970] O-J. Dahl, B. Myrhaug, and K. Nygaard: SIMULA Common Base Language.
Norwegian Computing Center S-22. Oslo, Norway. 1970.
[Dahl,1972] O-J. Dahl and C. A. R. Hoare: Hierarchical Program Construction in Structured
Programming. Academic Press, New York. 1972.
[Ellis,1989] Margaret A. Ellis and Bjarne Stroustrup: The Annotated C++ Reference Manual.
Addison-Wesley. Reading, Mass. 1990. ISBN 0-201-51459-1.
[Gamma,1995] Eric Gamma, et al.: Design Patterns. Addison-Wesley. Reading, Mass. 1995.
ISBN 0-201-63361-2.
[Goldberg,1983] A. Goldberg and D. Robson: SMALLTALK-80 – The Language and Its Implementation.
Addison-Wesley. Reading, Mass. 1983.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
18 Notes to the Reader Chapter 1
[Griswold,1970] R. E. Griswold, et al.: The Snobol4 Programming Language. Prentice-Hall.
Englewood Cliffs, New Jersey. 1970.
[Griswold,1983] R. E. Griswold and M. T. Griswold: The ICON Programming Language.
Prentice-Hall. Englewood Cliffs, New Jersey. 1983.
[Hamilton,1993] G. Hamilton and P. Kougiouris: The Spring Nucleus: A Microkernel for
Objects. Proc. 1993 Summer USENIX Conference. USENIX.
[Henricson,1997] Mats Henricson and Erik Nyquist: Industrial Strength C++: Rules and Recommendations.
Prentice-Hall. Englewood Cliffs, New Jersey. 1997. ISBN 0-
13-120965-5.
[Ichbiah,1979] Jean D. Ichbiah, et al.: Rationale for the Design of the ADA Programming Language.
SIGPLAN Notices. Vol. 14 No. 6. June 1979.
[Kamath,1993] Ygeesh H. Kamath, Ruth E. Smilan, and Jean G. Smith: Reaping Benefits with
Object-Oriented Technology. AT&T Technical Journal. Vol. 72 No. 5.
September/October 1993.
[Kernighan,1978] Brian W. Kernighan and Dennis M. Ritchie: The C Programming Language.
Prentice-Hall. Englewood Cliffs, New Jersey. 1978.
[Kernighan,1988] Brian W. Kernighan and Dennis M. Ritchie: The C Programming Language
(Second Edition). Prentice-Hall. Englewood Cliffs, New Jersey. 1988. ISBN
0-13-110362-8.
[Koenig,1989] Andrew Koenig and Bjarne Stroustrup: C++: As close to C as possible – but
no closer. The C++ Report. Vol. 1 No. 7. July 1989.
[Koenig,1997] Andrew Koenig and Barbara Moo: Ruminations on C++. Addison Wesley
Longman. Reading, Mass. 1997. ISBN 1-201-42339-1.
[Knuth,1968] Donald Knuth: The Art of Computer Programming. Addison-Wesley. Reading,
Mass.
[Liskov,1979] Barbara Liskov et al.: Clu Reference Manual. MIT/LCS/TR-225. MIT Cambridge.
Mass. 1979.
[Martin,1995] Robert C. Martin: Designing Object-Oriented C++ Applications Using the
Booch Method. Prentice-Hall. Englewood Cliffs, New Jersey. 1995. ISBN
0-13-203837-4.
[Orwell,1949] George Orwell: 1984. Secker and Warburg. London. 1949.
[Parrington,1995] Graham Parrington et al.: The Design and Implementation of Arjuna. Computer
Systems. Vol. 8 No. 3. Summer 1995.
[Richards,1980] Martin Richards and Colin Whitby-Strevens: BCPL – The Language and Its
Compiler. Cambridge University Press, Cambridge. England. 1980. ISBN
0-521-21965-5.
[Rosler,1984] L. Rosler: The Evolution of C – Past and Future. AT&T Bell Laboratories
Technical Journal. Vol. 63 No. 8. Part 2. October 1984.
[Rozier,1988] M. Rozier, et al.: CHORUS Distributed Operating Systems. Computing Systems.
Vol. 1 No. 4. Fall 1988.
[Sethi,1981] Ravi Sethi: Uniform Syntax for Type Expressions and Declarations. Software
Practice & Experience. Vol. 11. 1981.
[Stepanov,1994] Alexander Stepanov and Meng Lee: The Standard Template Library. HP Labs
Technical Report HPL-94-34 (R. 1). August, 1994.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 1.8.1 References 19
[Stroustrup,1986] Bjarne Stroustrup: The C++ Programming Language. Addison-Wesley.
Reading, Mass. 1986. ISBN 0-201-12078-X.
[Stroustrup,1987] Bjarne Stroustrup and Jonathan Shopiro: A Set of C Classes for Co-Routine
Style Programming. Proc. USENIX C++ conference. Santa Fe, New Mexico.
November 1987.
[Stroustrup,1991] Bjarne Stroustrup: The C++ Programming Language (Second Edition).
Addison-Wesley. Reading, Mass. 1991. ISBN 0-201-53992-6.
[Stroustrup,1994] Bjarne Stroustrup: The Design and Evolution of C++. Addison-Wesley. Reading,
Mass. 1994. ISBN 0-201-54330-3.
[Tarjan,1983] Robert E. Tarjan: Data Structures and Network Algorithms. Society for Industrial
and Applied Mathematics. Philadelphia, Penn. 1983. ISBN 0-898-
71187-8.
[Unicode,1996] The Unicode Consortium: The Unicode Standard, Version 2.0. AddisonWesley
Developers Press. Reading, Mass. 1996. ISBN 0-201-48345-9.
[UNIX,1985] UNIX Time-Sharing System: Programmer’s Manual. Research Version, Tenth
Edition. AT&T Bell Laboratories, Murray Hill, New Jersey. February 1985.
[Wilson,1996] Gregory V. Wilson and Paul Lu (editors): Parallel Programming Using C++.
The MIT Press. Cambridge. Mass. 1996. ISBN 0-262-73118-5.
[Wikströ m,1987] Å ke Wikströ m: Functional Programming Using ML. Prentice-Hall. Englewood
Cliffs, New Jersey. 1987.
[Woodward,1974] P. M. Woodward and S. G. Bond: Algol 68-R Users Guide. Her Majesty’s Stationery
Office. London. England. 1974.
References to books relating to design and larger software development issues can be found at the
end of Chapter 23.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
20 Notes to the Reader Chapter 1
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
_ _ _______________________________________________________________________________________________________________________________ _______________________________________ ________________________________
2 _ _ _______________________________________________________________________________________________________________________________ _______________________________________ ________________________________
A Tour of C+ +
The first thing we do, let´s
kill all the language lawyers.
– Henry VI, part II
What is C++? — programming paradigms — procedural programming — modularity —
separate compilation — exception handling — data abstraction — user-defined types —
concrete types — abstract types — virtual functions — object-oriented programming —
generic programming — containers — algorithms — language and programming —
advice.
2.1 What is C++? [tour.intro]
C++ is a general-purpose programming language with a bias towards systems programming that
– is a better C,
– supports data abstraction,
– supports object-oriented programming, and
– supports generic programming.
This chapter explains what this means without going into the finer details of the language definition.
Its purpose is to give you a general overview of C++ and the key techniques for using it, not
to provide you with the detailed information necessary to start programming in C++.
If you find some parts of this chapter rough going, just ignore those parts and plow on. All will
be explained in detail in later chapters. However, if you do skip part of this chapter, do yourself a
favor by returning to it later.
Detailed understanding of language features – even of all features of a language – cannot compensate
for lack of an overall view of the language and the fundamental techniques for using it.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
22 A Tour of C++ Chapter 2
2.2 Programming Paradigms [tour.paradigm]
Object-oriented programming is a technique for programming – a paradigm for writing ‘‘good’’
programs for a set of problems. If the term ‘‘object-oriented programming language’’ means anything,
it must mean a programming language that provides mechanisms that support the objectoriented
style of programming well.
There is an important distinction here. A language is said to support a style of programming if
it provides facilities that make it convenient (reasonably easy, safe, and efficient) to use that style.
A language does not support a technique if it takes exceptional effort or skill to write such programs;
it merely enables the technique to be used. For example, you can write structured programs
in Fortran77 and object-oriented programs in C, but it is unnecessarily hard to do so because these
languages do not directly support those techniques.
Support for a paradigm comes not only in the obvious form of language facilities that allow
direct use of the paradigm, but also in the more subtle form of compile-time and/or run-time checks
against unintentional deviation from the paradigm. Type checking is the most obvious example of
this; ambiguity detection and run-time checks are also used to extend linguistic support for paradigms.
Extra-linguistic facilities such as libraries and programming environments can provide further
support for paradigms.
One language is not necessarily better than another because it possesses a feature the other does
not. There are many examples to the contrary. The important issue is not so much what features a
language possesses, but that the features it does possess are sufficient to support the desired programming
styles in the desired application areas:
[1] All features must be cleanly and elegantly integrated into the language.
[2] It must be possible to use features in combination to achieve solutions that would otherwise
require extra, separate features.
[3] There should be as few spurious and ‘‘special-purpose’’ features as possible.
[4] A feature’s implementation should not impose significant overheads on programs that do
not require it.
[5] A user should need to know only about the subset of the language explicitly used to write a
program.
The first principle is an appeal to aesthetics and logic. The next two are expressions of the ideal of
minimalism. The last two can be summarized as ‘‘what you don’t know won’t hurt you.’’
C++ was designed to support data abstraction, object-oriented programming, and generic programming
in addition to traditional C programming techniques under these constraints. It was not
meant to force one particular programming style upon all users.
The following sections consider some programming styles and the key language mechanisms
supporting them. The presentation progresses through a series of techniques starting with procedural
programming and leading up to the use of class hierarchies in object-oriented programming and
generic programming using templates. Each paradigm builds on its predecessors, each adds something
new to the C++ programmer’s toolbox, and each reflects a proven design approach.
The presentation of language features is not exhaustive. The emphasis is on design approaches
and ways of organizing programs rather than on language details. At this stage, it is far more
important to gain an idea of what can be done using C++ than to understand exactly how it can be
achieved.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 2.3 Procedural Programming 23
2.3 Procedural Programming [tour.proc]
The original programming paradigm is:
Decide which procedures you want;
use the best algorithms you can find.
The focus is on the processing – the algorithm needed to perform the desired computation. Languages
support this paradigm by providing facilities for passing arguments to functions and returning
values from functions. The literature related to this way of thinking is filled with discussion of
ways to pass arguments, ways to distinguish different kinds of arguments, different kinds of functions
(e.g., procedures, routines, and macros), etc.
A typical example of ‘‘good style’’ is a square-root function. Given a double-precision
floating-point argument, it produces a result. To do this, it performs a well-understood mathematical
computation:
double sqrt(double arg)
{
/ / code for calculating a square root
}
void f()
{
double root2= sqrt(2) ;
/ / ...
}
Curly braces, { }, express grouping in C++. Here, they indicate the start and end of the function
bodies. The double slash, / /, begins a comment that extends to the end of the line. The keyword
voidindicates that a function does not return a value.
From the point of view of program organization, functions are used to create order in a maze of
algorithms. The algorithms themselves are written using function calls and other language facilities.
The following subsections present a thumb-nail sketch of C++’s most basic facilities for
expressing computation.
2.3.1 Variables and Arithmetic [tour.var]
Every name and every expression has a type that determines the operations that may be performed
on it. For example, the declaration
int inch;
specifies that inchis of type int; that is, inchis an integer variable.
A declaration is a statement that introduces a name into the program. It specifies a type for that
name. A type defines the proper use of a name or an expression.
C++ offers a variety of fundamental types, which correspond directly to hardware facilities. For
example:
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
24 A Tour of C++ Chapter 2
bool/ / Boolean, possible values are true and false
char/ / character, for example, ’a’, ’z’, and ’9’
int/ / integer, for example, 1, 42, and 1216
double/ / double-precision floating-point number, for example, 3.14 and 299793.0
A charvariable is of the natural size to hold a character on a given machine (typically a byte), and
an intvariable is of the natural size for integer arithmetic on a given machine (typically a word).
The arithmetic operators can be used for any combination of these types:
+ / / plus, both unary and binary
- / / minus, both unary and binary
* / / multiply
/ / / divide
% / / remainder
So can the comparison operators:
== / / equal
!= / / not equal
< / / less than
> / / greater than
<= / / less than or equal
>= / / greater than or equal
In assignments and in arithmetic operations, C++ performs all meaningful conversions between the
basic types so that they can be mixed freely:
void some_function() / / function that doesn’t return a value
{
double d= 2.2; / / initialize floating-point number
int i= 7; / / initialize integer
d= d+i; / / assign sum to d
i= d*i; / / assign product to i
}
As in C, = is the assignment operator and == tests equality.
2.3.2 Tests and Loops [tour.loop]
C++ provides a conventional set of statements for expressing selection and looping. For example,
here is a simple function that prompts the user and returns a Boolean indicating the response:
bool accept()
{
cout<< "Do you want to proceed(y or n)?\n"; / / write question
char answer= 0;
cin>> answer; / / read answer
if(answer== ´y´) return true;
return false;
}
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 2.3.2 Tests and Loops 25
The << operator (‘‘put to’’) is used as an output operator; coutis the standard output stream. The
>> operator (‘‘get from’’) is used as an input operator; cinis the standard input stream. The type of
the right-hand operand of >> determines what input is accepted and is the target of the input operation.
The \ncharacter at the end of the output string represents a newline.
The example could be slightly improved by taking an ‘n’ answer into account:
bool accept2()
{
cout<< "Do you want to proceed(y or n)?\n"; / / write question
char answer= 0;
cin>> answer; / / read answer
switch(answer) {
case´y´:
return true;
case´n´:
return false;
default:
cout<< "I´ll take that for a no.\n";
return false;
}
}
A switch-statement tests a value against a set of constants. The case constants must be distinct, and
if the value tested does not match any of them, the defaultis chosen. The programmer need not
provide a default.
Few programs are written without loops. In this case, we might like to give the user a few tries:
bool accept3()
{
int tries= 1;
while(tries< 4) {
cout<< "Do you want to proceed(y or n)?\n"; / / write question
char answer= 0;
cin>> answer; / / read answer
switch(answer) {
case´y´:
return true;
case´n´:
return false;
default:
cout<< "Sorry, I don´t understand that.\n";
tries= tries+ 1;
}
}
cout<< "I´ll take that for a no.\n";
return false;
}
The while-statement executes until its condition becomes false.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
26 A Tour of C++ Chapter 2
2.3.3 Pointers and Arrays [tour.ptr]
An array can be declared like this:
char v[10] ; / / array of 10 characters
Similarly, a pointer can be declared like this:
char* p; / / pointer to character
In declarations, [] means ‘‘array of’’ and * means ‘‘pointer to.’’ All arrays have 0as their lower
bound, so vhas ten elements, v[0]...v[9]. A pointer variable can hold the address of an object of
the appropriate type:
p= &v[3] ; / / p points to v’s fourth element
Unary & is the address-of operator.
Consider copying ten elements from one array to another:
void another_function()
{
int v1[10] ;
int v2[10] ;
/ / ...
for(int i=0; i<10; ++i) v1[i]=v2[i] ;
}
This for-statement can be read as ‘‘set ito zero, while iis less than 10, copy the ith element and
increment i.’’ When applied to an integer variable, the increment operator ++ simply adds 1.
2.4 Modular Programming [tour.module]
Over the years, the emphasis in the design of programs has shifted from the design of procedures
and toward the organization of data. Among other things, this reflects an increase in program size.
A set of related procedures with the data they manipulate is often called a module. The programming
paradigm becomes:
Decide which modules you want;
partition the program so that data is hidden within modules.
This paradigm is also known as the data-hiding principle. Where there is no grouping of procedures
with related data, the procedural programming style suffices. Also, the techniques for designing
‘‘good procedures’’ are now applied for each procedure in a module. The most common example
of a module is the definition of a stack. The main problems that have to be solved are:
[1] Provide a user interface for the stack (e.g., functions push() and pop()).
[2] Ensure that the representation of the stack (e.g., an array of elements) can be accessed only
through this user interface.
[3] Ensure that the stack is initialized before its first use.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 2.4 Modular Programming 27
C++ provides a mechanism for grouping related data, functions, etc., into separate namespaces. For
example, the user interface of a Stackmodule could be declared and used like this:
namespace Stack{ / / interface
void push(char) ;
char pop() ;
}
void f()
{
Stack: :push(´c´) ;
if(Stack: :pop() != ´c´) error("impossible") ;
}
The Stack: : qualification indicates that the push() and pop() are those from the Stacknamespace.
Other uses of those names will not interfere or cause confusion.
The definition of the Stackcould be provided in a separately-compiled part of the program:
namespace Stack{ / / implementation
const int max_size= 200;
char v[max_size] ;
int top= 0;
void push(char c) { /* check for overflow and push c */ }
char pop() { /* check for underflow and pop */ }
}
The key point about this Stackmodule is that the user code is insulated from the data representation
of Stackby the code implementing Stack: :push() and Stack: :pop(). The user doesn’t need to
know that the Stackis implemented using an array, and the implementation can be changed without
affecting user code.
Because data is only one of the things one might want to ‘‘hide,’’ the notion of data hiding is
trivially extended to the notion of information hiding; that is, the names of functions, types, etc.,
can also be made local to a module. Consequently, C++ allows any declaration to be placed in a
namespace (§8.2).
This Stackmodule is one way of representing a stack. The following sections use a variety of
stacks to illustrate different programming styles.
2.4.1 Separate Compilation [tour.comp]
C++ supports C’s notion of separate compilation. This can be used to organize a program into a set
of semi-independent fragments.
Typically, we place the declarations that specify the interface to a module in a file with a name
indicating its intended use. Thus,
namespace Stack{ / / interface
void push(char) ;
char pop() ;
}
would be placed in a file stack.h, and users will include that file, called a header file, like this:
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
28 A Tour of C++ Chapter 2
#include"stack.h" / / get the interface
void f()
{
Stack: :push(´c´) ;
if(Stack: :pop() != ´c´) error("impossible") ;
}
To help the compiler ensure consistency, the file providing the implementation of the Stackmodule
will also include the interface:
#include"stack.h" / / get the interface
namespace Stack{ / / representation
const int max_size= 200;
char v[max_size] ;
int top= 0;
}
void Stack: :push(char c) { /* check for overflow and push c */ }
char Stack: :pop() { /* check for underflow and pop */ }
The user code goes in a third file, say user.c. The code in user.cand stack.cshares the stack
interface information presented in stack.h, but the two files are otherwise independent and can be
separately compiled. Graphically, the program fragments can be represented like this:
Stack interface
. .
#include "stack.h"
use stack
. .
#include "stack.h"
define stack
.
stack.h:
user.c: stack.c:
Separate compilation is an issue in all real programs. It is not simply a concern in programs that
present facilities, such as a Stack, as modules. Strictly speaking, using separate compilation isn’t a
language issue; it is an issue of how best to take advantage of a particular language implementation.
However, it is of great practical importance. The best approach is to maximize modularity, represent
that modularity logically through language features, and then exploit the modularity physically
through files for effective separate compilation (Chapter 8, Chapter 9).
2.4.2 Exception Handling [tour.except]
When a program is designed as a set of modules, error handling must be considered in light of these
modules. Which module is responsible for handling what errors? Often, the module that detects an
error doesn’t know what action to take. The recovery action depends on the module that invoked
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 2.4.2 Exception Handling 29
the operation rather than on the module that found the error while trying to perform the operation.
As programs grow, and especially when libraries are used extensively, standards for handling errors
(or, more generally, ‘‘exceptional circumstances’’) become important.
Consider again the Stackexample. What ought to be done when we try to push() one too
many characters? The writer of the Stackmodule doesn’t know what the user would like to be
done in this case, and the user cannot consistently detect the problem (if the user could, the overflow
wouldn’t happen in the first place). The solution is for the Stackimplementer to detect the
overflow and then tell the (unknown) user. The user can then take appropriate action. For example:
namespace Stack{ / / interface
void push(char) ;
char pop() ;
class Overflow{ }; / / type representing overflow exceptions
}
When detecting an overflow, Stack: :push() can invoke the exception-handling code; that is,
‘‘throw an Overflowexception:’’
void Stack: :push(char c)
{
if(top== max_size) throw Overflow() ;
/ / push c
}
The throwtransfers control to a handler for exceptions of type Stack: :Overflowin some function
that directly or indirectly called Stack: :push(). To do that, the implementation will unwind the
function call stack as needed to get back to the context of that caller. Thus, the throwacts as a multilevel
return. For example:
void f()
{
/ / ...
try{ / / exceptions here are handled by the handler defined below
while(true) Stack: :push(´c´) ;
}
catch(Stack: :Overflow) {
/ / oops: stack overflow; take appropriate action
}
/ / ...
}
The whileloop will try to loop forever. Therefore, the catch-clause providing a handler for
Stack: :Overflowwill be entered after some call of Stack: :push() causes a throw.
Use of the exception-handling mechanisms can make error handling more regular and readable.
See §8.3 and Chapter 14 for further discussion and details.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
30 A Tour of C++ Chapter 2
2.5 Data Abstraction [tour.da]
Modularity is a fundamental aspect of all successful large programs. It remains a focus of all
design discussions throughout this book. However, modules in the form described previously are
not sufficient to express complex systems cleanly. Here, I first present a way of using modules to
provide a form of user-defined types and then show how to overcome some problems with that
approach by defining user-defined types directly.
2.5.1 Modules Defining Types [tour.types]
Programming with modules leads to the centralization of all data of a type under the control of a
type manager module. For example, if we wanted many stacks – rather than the single one provided
by the Stackmodule above – we could define a stack manager with an interface like this:
namespace Stack{
struct Rep; / / definition of stack layout is elsewhere
typedef Rep& stack;
stack create() ; / / make a new stack
void destroy(stack s) ; / / delete s
void push(stack s, char c) ; / / push c onto s
char pop(stack s) ; / / pop s
}
The declaration
struct Rep;
says that Repis the name of a type, but it leaves the type to be defined later (§5.7). The declaration
typedef Rep& stack;
gives the name stackto a ‘‘reference to Rep’’ (details in §5.5). The idea is that a stack is identified
by its Stack: :stackand that further details are hidden from users.
A Stack: :stackacts much like a variable of a built-in type:
struct Bad_pop{ };
void f()
{
Stack: :stack s1= Stack: :create() ; / / make a new stack
Stack: :stack s2= Stack: :create() ; / / make another new stack
Stack: :push(s1,´c´) ;
Stack: :push(s2,´k´) ;
if(Stack: :pop(s1) != ´c´) throw Bad_pop() ;
if(Stack: :pop(s2) != ´k´) throw Bad_pop() ;
Stack: :destroy(s1) ;
Stack: :destroy(s2) ;
}
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 2.5.1 Modules Defining Types 31
We could implement this Stackin several ways. It is important that a user doesn’t need to know
how we do it. As long as we keep the interface unchanged, a user will not be affected if we decide
to re-implement Stack.
An implementation might preallocate a few stack representations and let Stack: :create() hand
out a reference to an unused one. Stack: :destroy() could then mark a representation ‘‘unused’’
so that Stack: :create() can recycle it:
namespace Stack{ / / representation
const int max_size= 200;
struct Rep{
char v[max_size] ;
int top;
};
const int max= 16; / / maximum number of stacks
Rep stacks[max] ; / / preallocated stack representations
bool used[max] ; / / used[i] is true if stacks[i] is in use
}
void Stack: :push(stack s, char c) { /* check s for overflow and push c */ }
char Stack: :pop(stack s) { /* check s for underflow and pop */ }
Stack: :stack Stack: :create()
{
/ / pick an unused Rep, mark it used, initialize it, and return a reference to it
}
void Stack: :destroy(stack s) { /* mark s unused */ }
What we have done is to wrap a set of interface functions around the representation type. How the
resulting ‘‘stack type’’ behaves depends partly on how we defined these interface functions, partly
on how we presented the representation type to the users of Stacks, and partly on the design of the
representation type itself.
This is often less than ideal. A significant problem is that the presentation of such ‘‘fake types’’
to the users can vary greatly depending on the details of the representation type – and users ought
to be insulated from knowledge of the representation type. For example, had we chosen to use a
more elaborate data structure to identify a stack, the rules for assignment and initialization of
Stack: :stacks would have changed dramatically. This may indeed be desirable at times. However,
it shows that we have simply moved the problem of providing convenient Stacks from the
Stackmodule to the Stack: :stackrepresentation type.
More fundamentally, user-defined types implemented through a module providing access to an
implementation type don’t behave like built-in types and receive less and different support than do
built-in types. For example, the time that a Stack: :Repcan be used is controlled through
Stack: :create() and Stack: :destroy() rather than by the usual language rules.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
32 A Tour of C++ Chapter 2
2.5.2 User-Defined Types [tour.udt]
C++ attacks this problem by allowing a user to directly define types that behave in (nearly) the
same way as built-in types. Such a type is often called an abstract data type. I prefer the term
user-defined type. A more reasonable definition of abstract data type would require a mathematical
‘‘abstract’’ specification. Given such a specification, what are called types here would be concrete
examples of such truly abstract entities. The programming paradigm becomes:
Decide which types you want;
provide a full set of operations for each type.
Where there is no need for more than one object of a type, the data-hiding programming style using
modules suffices.
Arithmetic types such as rational and complex numbers are common examples of user-defined
types. Consider:
class complex{
double re, im;
public:
complex(double r, double i) { re=r; im=i; } / / construct complex from two scalars
complex(double r) { re=r; im=0; } / / construct complex from one scalar
complex() { re= im= 0; } / / default complex: (0,0)
friend complex operator+(complex, complex) ;
friend complex operator-(complex, complex) ; / / binary
friend complex operator-(complex) ; / / unary
friend complex operator*(complex, complex) ;
friend complex operator/(complex, complex) ;
friend bool operator==(complex, complex) ; / / equal
friend bool operator!=(complex, complex) ; / / not equal
/ / ...
};
The declaration of class (that is, user-defined type) complexspecifies the representation of a complex
number and the set of operations on a complex number. The representation is private; that is,
reand imare accessible only to the functions specified in the declaration of class complex. Such
functions can be defined like this:
complex operator+(complex a1, complex a2)
{
return complex(a1.re+a2.re,a1.im+a2.im) ;
}
A member function with the same name as its class is called a constructor. A constructor defines a
way to initialize an object of its class. Class complexprovides three constructors. One makes a
complexfrom a double, another takes a pair of doubles, and the third makes a complexwith a
default value.
Class complexcan be used like this:
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 2.5.2 User-Defined Types 33
void f(complex z)
{
complex a= 2.3;
complex b= 1/a;
complex c= a+b*complex(1,2.3) ;
/ / ...
if(c!= b) c= -(b/a)+2*b;
}
The compiler converts operators involving complexnumbers into appropriate function calls. For
example, c!=bmeans operator!=(c,b) and 1/ameans operator/(complex(1) ,a).
Most, but not all, modules are better expressed as user-defined types.
2.5.3 Concrete Types [tour.concrete]
User-defined types can be designed to meet a wide variety of needs. Consider a user-defined Stack
type along the lines of the complextype. To make the example a bit more realistic, this Stacktype
is defined to take its number of elements as an argument:
class Stack{
char* v;
int top;
int max_size;
public:
class Underflow{ }; / / used as exception
class Overflow{ }; / / used as exception
class Bad_size{ }; / / used as exception
Stack(int s) ; / / constructor
~Stack() ; / / destructor
void push(char c) ;
char pop() ;
};
The constructor Stack(int) will be called whenever an object of the class is created. This takes
care of initialization. If any cleanup is needed when an object of the class goes out of scope, a complement
to the constructor – called the destructor – can be declared:
Stack: :Stack(int s) / / constructor
{
top= 0;
if(10000push(´d´) ;
/ / ...
}
This Stacktype obeys the same rules for naming, scope, allocation, lifetime, copying, etc., as does
a built-in type such as intand char.
Naturally, the push() and pop() member functions must also be defined somewhere:
void Stack: :push(char c)
{
if(top== max_size) throw Overflow() ;
v[top] = c;
top= top+ 1;
}
char Stack: :pop()
{
if(top== 0) throw Underflow() ;
top= top- 1;
return v[top] ;
}
Types such as complexand Stackare called concrete types, in contrast to abstract types, where the
interface more completely insulates a user from implementation details.
2.5.4 Abstract Types [tour.abstract]
One property was lost in the transition from Stackas a ‘‘fake type’’ implemented by a module
(§2.5.1) to a proper type (§2.5.3). The representation is not decoupled from the user interface;
rather, it is a part of what would be included in a program fragment using Stacks. The representation
is private, and therefore accessible only through the member functions, but it is present. If it
changes in any significant way, a user must recompile. This is the price to pay for having concrete
types behave exactly like built-in types. In particular, we cannot have genuine local variables of a
type without knowing the size of the type’s representation.
For types that don’t change often, and where local variables provide much-needed clarity and
efficiency, this is acceptable and often ideal. However, if we want to completely isolate users of a
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 2.5.4 Abstract Types 35
stack from changes to its implementation, this last Stackis insufficient. Then, the solution is to
decouple the interface from the representation and give up genuine local variables.
First, we define the interface:
class Stack{
public:
class Underflow{ }; / / used as exception
class Overflow{ }; / / used as exception
virtual void push(char c) = 0;
virtual char pop() = 0;
};
The word virtualmeans ‘‘may be redefined later in a class derived from this one’’ in Simula and
C++. A class derived from Stackprovides an implementation for the Stackinterface. The curious
=0syntax says that some class derived from Stack must define the function. Thus, this Stackcan
serve as the interface to any class that implements its push() and pop() functions.
This Stackcould be used like this:
void f(Stack& s_ref)
{
s_ref.push(´c´) ;
if(s_ref.pop() != ´c´) throw bad_stack() ;
}
Note how f() uses the Stackinterface in complete ignorance of implementation details. A class
that provides the interface to a variety of other classes is often called a polymorphic type.
Not surprisingly, the implementation could consist of everything from the concrete class Stack
that we left out of the interface Stack:
class Array_stack: public Stack{ / / Array_stack implements Stack
char* p;
int max_size;
int top;
public:
Array_stack(int s) ;
~Array_stack() ;
void push(char c) ;
char pop() ;
};
The ‘‘:public’’ can be read as ‘‘is derived from,’’ ‘‘implements,’’ and ‘‘is a subtype of.’’
For a function like f() to use a Stackin complete ignorance of implementation details, some
other function will have to make an object on which it can operate. For example:
void g()
{
Array_stack as(200) ;
f(as) ;
}
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
36 A Tour of C++ Chapter 2
Since f() doesn’t know about Array_stacks but only knows the Stackinterface, it will work just as
well for a different implementation of a Stack. For example:
class List_stack: public Stack{ / / List_stack implements Stack
list lc; / / (standard library) list of characters (§3.7.3)
public:
List_stack() { }
void push(char c) { lc.push_front(c) ; }
char pop() ;
};
char List_stack: :pop()
{
char x= lc.front() ; / / get first element
lc.pop_front() ; / / remove first element
return x;
}
Here, the representation is a list of characters. The lc.push_front(c) adds cas the first element of
lc, the call lc.pop_front() removes the first element, and lc.front() denotes lc’s first element.
A function can create a List_stackand have f() use it:
void h()
{
List_stack ls;
f(ls) ;
}
2.5.5 Virtual Functions [tour.virtual]
How is the call s_set.pop() in f() resolved to the right function definition? When f() is called
from h(), List_stack: :pop() must be called. When f() is called from g(),
Array_stack: :pop() must be called. To achieve this resolution, a Stackobject must contain
information to indicate the function to be called at run-time. A common implementation technique
is for the compiler to convert the name of a virtualfunction into an index into a table of pointers to
functions. That table is usually called ‘‘a virtual function table’’ or simply, a vtbl. Each class with
virtual functions has its own vtblidentifying its virtual functions. This can be represented graphically
like this:
p
max_size
top
. . Array_stack::push()
Array_stack::pop()
Array_stack object:vtbl:
.
lc
. . List_stack::push()
List_stack::pop()
List_stack object:vtbl:
.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 2.5.5 Virtual Functions 37
The functions in the vtblallow the object to be used correctly even when the size of the object and
the layout of its data are unknown to the caller. All the caller needs to know is the location of the
vtblin a Stackand the index used for each virtual function. This virtual call mechanism can be
made essentially as efficient as the ‘‘normal function call’’ mechanism. Its space overhead is one
pointer in each object of a class with virtual functions plus one vtblfor each such class.
2.6 Object-Oriented Programming [tour.oop]
Data abstraction is fundamental to good design and will remain a focus of design throughout this
book. However, user-defined types by themselves are not flexible enough to serve our needs. This
section first demonstrates a problem with simple user-defined data types and then shows how to
overcome that problem by using class hierarchies.
2.6.1 Problems with Concrete Types [tour.problems]
A concrete type, like a ‘‘fake type’’ defined through a module, defines a sort of black box. Once
the black box has been defined, it does not really interact with the rest of the program. There is no
way of adapting it to new uses except by modifying its definition. This situation can be ideal, but it
can also lead to severe inflexibility. Consider defining a type Shapefor use in a graphics system.
Assume for the moment that the system has to support circles, triangles, and squares. Assume also
that we have
class Point{ /* ... */ };
class Color{ /* ... */ };
The /* and */ specify the beginning and end, respectively, of a comment. This comment notation
can be used for multi-line comments and comments that end before the end of a line.
We might define a shape like this:
enum Kind{ circle, triangle, square}; / / enumeration (§4.8)
class Shape{
Kind k; / / type field
Point center;
Color col;
/ / ...
public:
void draw() ;
void rotate(int) ;
/ / ...
};
The ‘‘type field’’ kis necessary to allow operations such as draw() and rotate() to determine
what kind of shape they are dealing with (in a Pascal-like language, one might use a variant record
with tag k). The function draw() might be defined like this:
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
38 A Tour of C++ Chapter 2
void Shape: :draw()
{
switch(k) {
case circle:
/ / draw a circle
break;
case triangle:
/ / draw a triangle
break;
case square:
/ / draw a square
break;
}
}
This is a mess. Functions such as draw() must ‘‘know about’’ all the kinds of shapes there are.
Therefore, the code for any such function grows each time a new shape is added to the system. If
we define a new shape, every operation on a shape must be examined and (possibly) modified. We
are not able to add a new shape to a system unless we have access to the source code for every
operation. Because adding a new shape involves ‘‘touching’’ the code of every important operation
on shapes, doing so requires great skill and potentially introduces bugs into the code that handles
other (older) shapes. The choice of representation of particular shapes can get severely cramped by
the requirement that (at least some of) their representation must fit into the typically fixed-sized
framework presented by the definition of the general type Shape.
2.6.2 Class Hierarchies [tour.hierarchies]
The problem is that there is no distinction between the general properties of every shape (that is, a
shape has a color, it can be drawn, etc.) and the properties of a specific kind of shape (a circle is a
shape that has a radius, is drawn by a circle-drawing function, etc.). Expressing this distinction and
taking advantage of it defines object-oriented programming. Languages with constructs that allow
this distinction to be expressed and used support object-oriented programming. Other languages
don’t.
The inheritance mechanism (borrowed for C++ from Simula) provides a solution. First, we
specify a class that defines the general properties of all shapes:
class Shape{
Point center;
Color col;
/ / ...
public:
Point where() { return center; }
void move(Point to) { center= to; /* ... */ draw() ; }
virtual void draw() = 0;
virtual void rotate(int angle) = 0;
/ / ...
};
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 2.6.2 Class Hierarchies 39
As in the abstract type Stackin §2.5.4, the functions for which the calling interface can be defined
– but where the implementation cannot be defined yet – are virtual. In particular, the functions
draw() and rotate() can be defined only for specific shapes, so they are declared virtual.
Given this definition, we can write general functions manipulating vectors of pointers to shapes:
void rotate_all(vector& v, int angle) / / rotate v’s elements angle degrees
{
for(int i= 0; irotate(angle) ;
}
To define a particular shape, we must say that it is a shape and specify its particular properties
(including the virtual functions):
class Circle: public Shape{
int radius;
public:
void draw() { /* ... */ }
void rotate(int) {} / / yes, the null function
};
In C++, class Circleis said to be derived from class Shape, and class Shapeis said to be a base of
class Circle. An alternative terminology calls Circleand Shapesubclass and superclass, respectively.
The derived class is said to inherit members from its base class, so the use of base and
derived classes is commonly referred to as inheritance.
The programming paradigm is:
Decide which classes you want;
provide a full set of operations for each class;
make commonality explicit by using inheritance.
Where there is no such commonality, data abstraction suffices. The amount of commonality
between types that can be exploited by using inheritance and virtual functions is the litmus test of
the applicability of object-oriented programming to a problem. In some areas, such as interactive
graphics, there is clearly enormous scope for object-oriented programming. In other areas, such as
classical arithmetic types and computations based on them, there appears to be hardly any scope for
more than data abstraction, and the facilities needed for the support of object-oriented programming
seem unnecessary.
Finding commonality among types in a system is not a trivial process. The amount of commonality
to be exploited is affected by the way the system is designed. When a system is designed –
and even when the requirements for the system are written – commonality must be actively sought.
Classes can be designed specifically as building blocks for other types, and existing classes can be
examined to see if they exhibit similarities that can be exploited in a common base class.
For attempts to explain what object-oriented programming is without recourse to specific programming
language constructs, see [Kerr,1987] and [Booch,1994] in §23.6.
Class hierarchies and abstract classes (§2.5.4) complement each other instead of being mutually
exclusive (§12.5). In general, the paradigms listed here tend to be complementary and often
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
40 A Tour of C++ Chapter 2
mutually supportive. For example, classes and modules contain functions, while modules contain
classes and functions. The experienced designer applies a variety of paradigms as need dictates.
2.7 Generic Programming [tour.generic]
Someone who wants a stack is unlikely always to want a stack of characters. A stack is a general
concept, independent of the notion of a character. Consequently, it ought to be represented independently.
More generally, if an algorithm can be expressed independently of representation details and if
it can be done so affordably and without logical contortions, it ought to be done so.
The programming paradigm is:
Decide which algorithms you want;
parameterize them so that they work for
a variety of suitable types and data structures.
2.7.1 Containers [tour.containers]
We can generalize a stack-of-characters type to a stack-of-anything type by making it a template
and replacing the specific type charwith a template parameter. For example:
template class Stack{
T* v;
int max_size;
int top;
public:
class Underflow{ };
class Overflow{ };
Stack(int s) ; / / constructor
~Stack() ; / / destructor
void push(T) ;
T pop() ;
};
The template prefix makes Ta parameter of the declaration it prefixes.
The member functions might be defined similarly:
template void Stack: :push(T c)
{
if(top== max_size) throw Overflow() ;
v[top] = c;
top= top+ 1;
}
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 2.7.1 Containers 41
template T Stack: :pop()
{
if(top== 0) throw Underflow() ;
top= top- 1;
return v[top] ;
}
Given these definitions, we can use stacks like this:
Stack sc; / / stack of characters
Stack scplx; / / stack of complex numbers
Stack< list > sli; / / stack of list of integers
void f()
{
sc.push(´c´) ;
if(sc.pop() != ´c´) throw Bad_pop() ;
scplx.push(complex(1,2)) ;
if(scplx.pop() != complex(1,2)) throw Bad_pop() ;
}
Similarly, we can define lists, vectors, maps (that is, associative arrays), etc., as templates. A class
holding a collection of elements of some type is commonly called a container class, or simply a
container.
Templates are a compile-time mechanism so that their use incurs no run-time overhead compared
to ‘‘hand-written code.’’
2.7.2 Generic Algorithms [tour.algorithms]
The C++ standard library provides a variety of containers, and users can write their own (Chapter 3,
Chapter 17, Chapter 18). Thus, we find that we can apply the generic programming paradigm once
more to parameterize algorithms by containers. For example, we want to sort, copy, and search
vectors, lists, and arrays without having to write sort(), copy(), and search() functions for each
container. We also don’t want to convert to a specific data structure accepted by a single sort function.
Therefore, we must find a generalized way of defining our containers that allows us to manipulate
one without knowing exactly which kind of container it is.
One approach, the approach taken for the containers and non-numerical algorithms in the C++
standard library (§3.8, Chapter 18) is to focus on the notion of a sequence and manipulate
sequences through iterators.
Here is a graphical representation of the notion of a sequence:
begin end
... . . . . ..
.
. .. . . . .
.
.
. elements:
A sequence has a beginning and an end. An iterator refers to an element, and provides an operation
that makes the iterator refer to the next element of the sequence. The end of a sequence is an
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
42 A Tour of C++ Chapter 2
iterator that refers one beyond the last element of the sequence. The physical representation of
‘‘the end’’ may be a sentinel element, but it doesn’t have to be. In fact, the point is that this notion
of sequences covers a wide variety of representations, including lists and arrays.
We need some standard notation for operations such as ‘‘access an element through an iterator’’
and ‘‘make the iterator refer to the next element.’’ The obvious choices (once you get the idea) are
to use the dereference operator * to mean ‘‘access an element through an iterator’’ and the increment
operator ++ to mean ‘‘make the iterator refer to the next element.’’
Given that, we can write code like this:
template void copy(In from, In too_far, Out to)
{
while(from!= too_far) {
*to= *from; / / copy element pointed to
++to; / / next input
++from; / / next output
}
}
This copies any container for which we can define iterators with the right syntax and semantics.
C++’s built-in, low-level array and pointer types have the right operations for that, so we can
write
char vc1[200] ; / / array of 200 characters
char vc2[500] ; / / array of 500 characters
void f()
{
copy(&vc1[0] ,&vc1[200] ,&vc2[0]) ;
}
This copies vc1from its first element until its last into vc2starting at vc2’s first element.
All standard library containers (§16.3, Chapter 17) support this notion of iterators and
sequences.
Two template parameters Inand Outare used to indicate the types of the source and the target
instead of a single argument. This was done because we often want to copy from one kind of container
into another. For example:
complex ac[200] ;
void g(vector& vc, list& lc)
{
copy(&ac[0] ,&ac[200] ,lc.begin()) ;
copy(lc.begin() ,lc.end() ,vc.begin()) ;
}
This copies the array to the listand the listto the vector. For a standard container, begin() is an
iterator pointing to the first element.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 2.8 Postscript 43
2.8 Postscript [tour.post]
No programming language is perfect. Fortunately, a programming language does not have to be
perfect to be a good tool for building great systems. In fact, a general-purpose programming language
cannot be perfect for all of the many tasks to which it is put. What is perfect for one task is
often seriously flawed for another because perfection in one area implies specialization. Thus, C++
was designed to be a good tool for building a wide variety of systems and to allow a wide variety of
ideas to be expressed directly.
Not everything can be expressed directly using the built-in features of a language. In fact, that
isn’t even the ideal. Language features exist to support a variety of programming styles and techniques.
Consequently, the task of learning a language should focus on mastering the native and
natural styles for that language – not on the understanding of every little detail of all the language
features.
In practical programming, there is little advantage in knowing the most obscure language features
or for using the largest number of features. A single language feature in isolation is of little
interest. Only in the context provided by techniques and by other features does the feature acquire
meaning and interest. Thus, when reading the following chapters, please remember that the real
purpose of examining the details of C++ is to be able to use them in concert to support good programming
style in the context of sound designs.
2.9 Advice [tour.advice]
[1] Don’t panic! All will become clear in time; §2.1.
[2] You don’t have to know every detail of C++ to write good programs; §1.7.
[3] Focus on programming techniques, not on language features; §2.1.
.
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
44 A Tour of C++ Chapter 2
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
_ _ _______________________________________________________________________________________________________________________________ _______________________________________ ________________________________
3 _ _ _______________________________________________________________________________________________________________________________ _______________________________________ ________________________________
A Tour of the Standard Library
Why waste time learning
when ignorance is instantaneous?
– Hobbes
Standard libraries — output — strings — input — vectors — range checking — lists —
maps — container overview — algorithms — iterators — I/O iterators — traversals and
predicates — algorithms using member functions — algorithm overview — complex
numbers — vector arithmetic— standard library overview — advice.
3.1 Introduction [tour2.lib]
No significant program is written in just a bare programming language. First, a set of supporting
libraries are developed. These then form the basis for further work.
Continuing Chapter 2, this chapter gives a quick tour of key library facilities to give you an idea
what can be done using C++ and its standard library. Useful library types, such as string, vector,
list, and map, are presented as well as the most common ways of using them. Doing this allows me
to give better examples and to set better exercises in the following chapters. As in Chapter 2, you
are strongly encouraged not to be distracted or discouraged by an incomplete understanding of
details. The purpose of this chapter is to give you a taste of what is to come and to convey an
understanding of the simplest uses of the most useful library facilities. A more detailed introduction
to the standard library is given in §16.1.2.
The standard library facilities described in this book are part of every complete C++ implementation.
In addition to the standard C++ library, most implementations offer ‘‘graphical user interface’’
systems, often referred to as GUIs or window systems, for interaction between a user and a
program. Similarly, most application development environments provide ‘‘foundation libraries’’
that support corporate or industrial ‘‘standard’’ development and/or execution environments. I do
not describe such systems and libraries. The intent is to provide a self-contained description of C++
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
46 A Tour of the Standard Library Chapter 3
as defined by the standard and to keep the examples portable, except where specifically noted. Naturally,
a programmer is encouraged to explore the more extensive facilities available on most systems,
but that is left to exercises.
3.2 Hello, world! [tour2.hello]
The minimal C++ program is
int main() { }
It defines a function called main, which takes no arguments and does nothing.
Every C++ program must have a function named main(). The program starts by executing that
function. The intvalue returned by main(), if any, is the program’s return value to ‘‘the system.’’
If no value is returned, the system will receive a value indicating successful completion. A nonzero
value from main() indicates failure.
Typically, a program produces some output. Here is a program that writes out Hello, world!:
#include
int main()
{
std: :cout<< "Hello, world!\n";
}
The line #include instructs the compiler to include the declarations of the standard
stream I/O facilities as found in iostream. Without these declarations, the expression
std: :cout<< "Hello, world!\n"
would make no sense. The operator << (‘‘put to’’) writes its second argument onto its first. In this
case, the string literal "Hello, world!\n" is written onto the standard output stream std: :cout. A
string literal is a sequence of characters surrounded by double quotes. In a string literal, the backslash
character \followed by another character denotes a single special character. In this case, \nis
the newline character, so that the characters written are Hello, world! followed by a newline.
3.3 The Standard Library Namespace [tour2.name]
The standard library is defined in a namespace (§2.4, §8.2) called std. That is why I wrote
std: :coutrather than plain cout. I was being explicit about using the standard cout, rather than
some other cout.
Every standard library facility is provided through some standard header similar to .
For example:
#include
#include
-
This makes the standard stringand listavailable. To use them, the std: : prefix can be used:
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 3.3 The Standard Library Namespace 47
std: :string s= "Four legs Good; two legs Baaad!";
std: :list
- ,
No comments:
Post a Comment