Home > Store

Effective C++: 50 Specific Ways to Improve Your Programs and Designs

Register your product to gain access to bonus material or receive a coupon.

Effective C++: 50 Specific Ways to Improve Your Programs and Designs

Book

  • Sorry, this book is no longer in print.
Not for Sale

Description

  • Copyright 1992
  • Edition: 1st
  • Book
  • ISBN-10: 0-201-56364-9
  • ISBN-13: 978-0-201-56364-1

Second Edition
now available!

"This is a 193-page masterpiece that I read in one sitting... I guarantee that some combination of these 50 items will grab and enlighten you, and repay your modest investment... This is a well-written, honest book aimed at C++ programmers who are converging toward fluency and effectiveness."
-- Stan Kelly-Bootle, Unix Review

Scott Meyers presents 50 concise rules based on what experienced C++ developers almost always do - or almost always avoid - to create efficient, portable, and maintainable software. Each rule is accompanied by examples that illustrate the rule at work. If you want to be a proficient C++ programmer, you will need to understand the complex interactions between the many features in the language. This incisive guide offers insight into the most important interactions.

Among its unique benefits, this book offers:

  • Expert guidance on object-oriented design, class design, and the proper use of inheritance

  • Innovative ways to simulate features your compiler may not have

  • Accumulated wisdom traditionally passed informally from programmer to programmer

This book corresponds to the definition of C++, including templates and exceptions, found in The Annotated C++ Reference Manual by Ellis and Stroustrup, and is also must reading for programmers with compilers supporting earlier versions of the language. With this book, you will learn how to write large scale software even if your compiler does not provide for nested types, templates, or exceptions. Meyers assumes a working knowledge of C++.



0201563649B04062001

Sample Content

Table of Contents

Shifting from C to C++.
Item 1: Use const and inline instead of #define.
Item 2: Prefer iostream.h to stdio.h.
Item 3: Use new and delete instead of malloc and free.
Item 4: Prefer C++-style comments.

Memory Management.
Item 5: Use the same form in corresponding calls to new and delete.
Item 6: Call delete on pointer members in destructors.
Item 7: Check the return value of new.
Item 8: Adhere to convention when writing new.
Item 9: Avoid hiding the global new.
Item 10: Write delete if you write new.

Constructors, Destructors, and Assignment Operators.
Item 11: Define a copy constructor and an assignment operator for classes with dynamically allocated memory.
Item 12: Prefer initialization to assignment in constructors.
Item 13: List members in an initialization list in the order in which they are declared.
Item 14: Make destructors virtual in base classes.
Item 15: Have operator= return a reference to *this.
Item 16: Assign to all data members in operator=.
Item 17: Check for assignment to self in operator=.
Classes and Functions: Design and Declaration.
Item 18: Strive for class interfaces that are complete and minimal.
Item 19: Differentiate among member functions, global functions, and friend functions.
Item 20: Avoid data members in the public interface.
Item 21: Use const whenever possible.
Item 22: Pass and return objects by reference instead of by value.
Item 23: Don't try to return a reference when you must return an object.
Item 24: Choose carefully between function overloading and parameter defaulting.
Item 25: Avoid overloading on a pointer and a numerical type.
Item 26: Guard against potential ambiguity.
Item 27: Explicitly disallow use of implicitly generated member functions you don't want.
Item 28: Use structs to partition the global namespace.

Classes and Functions: Implementation.
Item 29: Avoid returning "handles" to internal data from const member functions.
Item 30: Avoid member functions that return pointers or references to members less accessible than themselves.
Item 31: Never return a reference to a local object or a dereferenced pointer initialized by new within the function.
Item 32: Use enums for integral class constants.
Item 33: Use inlining judiciously.
Item 34: Minimize compilation dependencies between files.

Inheritance and Object-Oriented Design.
Item 35: Make sure public inheritance models "isa".
Item 36: Differentiate between inheritance of interface and inheritance of implementation.
Item 37: Never redefine an inherited nonvirtual function.
Item 38: Never redefine an inherited default parameter value.
Item 39: Avoid casts down the inheritance hierarchy.
Item 40: Model "has-a" or "is-implemented-in-terms-of" through layering.
Item 41: Use private inheritance judiciously.
Item 42: Differentiate between inheritance and templates.
Item 43: Use multiple inheritance judiciously.
Item 44: Say what you mean; understand what you're saying.

Miscellany.
Item 45: Know what functions C++ silently writes and calls.
Item 46: Prefer compile-time and link-time errors to runtime errors.
Item 47: Ensure that global objects are initialized before they're used.
Item 48: Pay attention to compiler warnings.
Item 49: Plan for coming language features.
Item 50: Read the ARM.

Index. 0201563649T04062001
020156364T07172001

Preface

This book is a direct outgrowth of my experiences teaching C++ to professional programmers through the Institute for Advanced Professional Studies. I found that most students, after a week of intensive instruction, felt comfortable with the basic constructs of the language, but were less sanguine about their ability to put the constructs together in an effective manner. Thus began my attempt to formulate short, specific, easy-to-remember guidelines for effective software development in C++: a summary of the things that experienced C++ programmers either almost always do or almost always avoid.

As a computer scientist, I was originally interested in rules that could be checked by a machine. To that end, I outlined a program to examine C++ software for constructs that were "almost always wrong." Currently under development, this checking program has become known as lint++. However, it quickly became apparent that the great majority of the guidelines used by good C++ programmers were too difficult to formalize, or had too many important exceptions, to be blindly enforced by a lint++-like program.

That led me to the notion of something less precise than a computer program but still more focused and to-the-point than a general C++ textbook. The result you now hold in your hands: a book containing 50 specific suggestions on how to improve your C++ programs and designs.

In this book you'll find advice on what you should do, and why, and what you should not do, and why not. Fundamentally, of course, the whys are much more important than the whats, but from a purely pragmatic point of view, it is much more convenient to have a list of guidelines in front of you than it is to memorize a textbook or two. Unlike most books on C++, my presentation here is not organized around particular language features. That is, I don't talk about constructors in one place, aboutvirtual functions in another, about inheritance in a third, etc. Instead, each explanation is tightly coupled to the specific guideline it accompanies, and my coverage of the various aspects of a particular feature is typically dispersed throughout the book.

The advantage of this approach is that it better reflects the complexity of the software systems for which C++ is often chosen, systems in which the understanding of individual language features is not enough. For example, experienced C++ developers know that understanding inline functions and understanding virtual destructors does not necessarily mean that you understand inline virtual destructors. Such battle-scarred developers recognize that comprehending the interactions between the features in C++ is of the greatest possible importance in using the language effectively. The organization of this book reflects that fundamental truth.

The disadvantage of my approach is that you may have to look in more than one place to discover everything I have to say about a particular construct in C++. To minimize the inconvenience inherent in this approach, I have sprinkled cross-references liberally throughout the text, and a comprehensive index is provided at the end of the book.

The set of guidelines in this book is far from exhaustive, but coming up with good rules - ones that are applicable to almost all applications almost all the time - is harder than it looks. Perhaps you know of additional guidelines, of more ways in which to program effectively in C++. If so, I would be delighted to hear about them.

On the other hand, you may feel that some of the items in this book are inappropriate as general advice; that there is a better way to accomplish a task examined in the book; or that one or more of the technical discussions is unclear, incomplete, or misleading. I encourage you to let me know about these things, too.

Donald Knuth has a long history of offering a small reward for people who notify him of errors in his books. The quest for a perfect book is laudable in any case, but in view of the number of bug-ridden C++ books that have been rushed to market, I feel especially strongly compelled to follow Knuth's example. Therefore, for each error in this book that is reported to me - be it technical, grammatical, typographical, or otherwise - I will, in future printings, gladly acknowledge the first person to report that error.

Send your suggested guidelines, your comments, your criticisms, and - sigh - your bug reports to:

Scott Meyersc/o Editor-in-Chief, Corporate and Professional Publishing
Addison-Wesley Publishing Company
1 Jacob Way
Reading, MA 01867
U. S. A.

Alternatively, you may send electronic mail to johnw@aw.com.

I maintain a list of changes to this book since its first printing, including bug-fixes, clarifications, and technical updates. This list is available via anonymous FTP from the Internet site ftp.aw.com in the directory cp/ec++. If you would like a copy of this file, but you lack access to the Internet, please send a request to one of the addresses above, and I will see that the list is sent to you.

Scott Douglas Meyers
Providence, RI
November 1991



0201563649P04062001

Updates

Errata

Modification History and Errata List
for Effective C++

Updated July 4, 1996

What follows is a list of substantive changes I've made to Effective C++ between printings. It is not a comprehensive list of modifications, because I've also fixed glitches in typesetting, spacing, spelling, etc., none of which affect the technical content of the book. I continue to solicit bug reports and suggestions for improvements to the book, but I do not anticipate making any more changes until I write a second edition. You can find the address to which comments should be sent at the end of the preface, page xiii.

To use this list, find out which printing of the book you have (it's listed on the copyright page near the bottom), then go to the appropriate section of the list and read from that point forward. For example, if you have a copy of the third printing, the changes made to the first printing won't apply to you (because the changes will already be in place in your copy of the book).

To be assured of always having the most accurate version of Effective C++ at your fingertips, I advise you to buy a copy of each printing :-).

* * * * *

The following changes were made between the first and second printings; you
need to worry about these changes only if you have a copy of the first
printing of the book:


  PAGES                                MODIFICATION
  ------  ----------------------------------------------------------------------
  6, 7    All the String constructors taking char* arguments should take
  15, 19  const char* arguments instead.
  34, 48  
  55, 69  
  74, 76  
  97, 99  
  174  

  14      Note that the ANSI committee is developing a standard for iostreams.

  19      The results of calling delete on an array w/o the brackets is
          ALWAYS undefined.  The book says it's okay, but only the first
          element in the array will be destructed.  This is wrong twice on
          this page.

  19      "and second, more constructors" ==> "and second, one or more
          constructors"

  24      "::new X;" ==> "::new char[size];"  I added a forward reference to
          Item 8, where the reason for calling new char is explained.

  25      currentHandler should be initialized once per loop iteration, not once
          per function call.  I moved the initialization of currentHandler
          inside the loop.

  28      In the inline op new, "::new X" ==> "new char[size]" 

  33      The void* pointer should be cast back to a char*, since new
          returned a char*.  Hence "::delete [] ((char*) deadObject);"

  46      At bottom of page, "delete ap" should be "delete pa" 

  67      Default value for denominator in class Rational should be 1, not 0.

  129     "Finally, we come to Airplane's nonvirtual" ==>      
          "...we come to Shape's nonvirtual"

  149     The default op= DOES call op= in base classes, so the user does
          not have to write his/her own.  That is, the default op= behaves
          similarly to the default copy constructor.

  160     "five different addresses" ==> "four different addresses"

  164     The text says that RealPerson inherits from Person.  This is not true;
          MyPerson inherits from Person.  I rewrote the paragraph to 
          improve the explanation.

  165     The text fails to explain why RealPerson's functions are
          protected.  This is because it's designed for use only as a base
          class; see also Item 41.

  173     The discussion of the default copy constructor and assignment operator
          makes no mention of what happens in an inheritance hierarchy.
          Basically, the same thing happens at every level of the hierarchy.

  187-8   The throw/catch clauses should take a const char*, not a char*.

  202     Add index entries for "member functions: protected"  and
  204     "protected member functions" for pages 127, 148-9, 156, 165.



The following changes were made between the third and fourth printings; you
need to worry about these changes only if you have a copy of one of the
first three printings of the book:

  PAGES                                MODIFICATION
  ------  ----------------------------------------------------------------------
  5       "declare arrays of objects"    ==> "define arrays of objects"
          "declare an array of pointers" ==> "define an array of pointers"
          "declaration of B"             ==> "definition of B"

  6       In operator+, insert "delete [] temp.data;" after declaring temp and
          before assigning to temp.data.  Otherwise there is a memory leak.

  15      To the list of books describing the iostream library, add 
          "C++ Programming and Fundamental Concepts," Arthur E. Anderson
          and William J. Heinze, Prentice Hall, 1992.

  31      In the code for Airplane::operator new: "new char[" ==> "::new char["

  37      It's not true that matching [] in new and delete is unimportant for the
          built-in types like char.  Omit "In the case of an object type
          ... but in general".

  47      "linker will complain" ==> "linker will probably complain" 

  67      Rational::operator* should be declared a const member function.

  68      The text at the top of the page implies that the compiler looks
          for an operator member function BEFORE searching the global
          scope, but in fact it searches both scopes simultaneously (see
          ARM p.  333).  I reworded things slightly.

  84      The cross-reference at the end of the first paragraph should be
          to Item 31, not Item 29.

  86      "The default constructor has to perform..." ==> 
          "The constructor taking an int has to perform" 

  87      "const void *NULL" ==> "const void * const NULL"      

  88      At the bottom of the page, all the NULL pointers should be const
          pointers to const.

  95      Omit trailing semicolon from macro definition for TRUE.

  95      "costs" ==> "is likely to cost"                       

  107     "enumerators are ints," ==> "the representation for an enumerator
          need not be any larger than that for an int,"

  109     2nd paragraph: the language states that inline functions have
          internal linkage, so compilers MUST treat inlines as if they'd
          been declared static.

  111-2   All the member functions returning char* should return const char*
  114-5   instead.  

  115     "is trivial and inline" ==> "is trivial"              

  118     "underestimated" ==> "overestimated"

  132     It's not true that default parameter values can only be in a
          declaration; they can also be in a definition.  In practice,
          however, they are always in the declaration, because they can't be
          in both places.

  134     "An object's dynamic type is the type of the object it currently
          refers to." ==> "An object's dynamic type is determined by the type
          of the object it currently refers to."

  149     The text says that by not declaring any constructors, Set acquires a
          copy constructor.  This is wrong.  By not declaring any COPY
          constructors, Set acquires a copy constructor.

  162     The statement implies that virtual bases cannot be used with SI.  I
          reworded things to eliminate this misimpression.  In practice, they
          rarely are.

  179     The 2nd bullet on page 179 should say "defined" instead of "declared".

  197     Add index entry for "conceptually const member functions" for page 76.



The following changes were made between the fifth and sixth printings; you
need to worry about these changes only if you have a copy of one of the first
five printings of the book:

  PAGES                                MODIFICATION
  ------  ----------------------------------------------------------------------

  xiii    Added email address for comment

Submit Errata

More Information

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.