Free Web Hosting Provider - Web Hosting - E-commerce - High Speed Internet - Free Web Page
Search the Web

DJ_RISHi

Thinking in C++, 2nd ed. Volume 1

©2007 by DJ_RISHi

[ Table of Contents ] [ Index ] [ Next Chapter ]

Preface

Like any human language, C++ provides a way to express concepts. If successful, this medium of expression will be significantly easier and more flexible than the alternatives as problems grow larger and more complex.

You can’t just look at C++ as a collection of features; some of the features make no sense in isolation. You can only use the sum of the parts if you are thinking about design, not simply coding. And to understand C++ this way, you must understand the problems with C and with programming in general. This book discusses programming problems, why they are problems, and the approach C++ has taken to solve such problems. Thus, the set of features I explain in each chapter will be based on the way that I see a particular type of problem being solved with the language. In this way I hope to move you, a little at a time, from understanding C to the point where the C++ mindset becomes your native tongue.

Throughout, I’ll be taking the attitude that you want to build a model in your head that allows you to understand the language all the way down to the bare metal; if you encounter a puzzle, you’ll be able to feed it to your model and deduce the answer. I will try to convey to you the insights that have rearranged my brain to make me start “thinking in C++.”

What’s new in the second edition

This book is a thorough rewrite of the first edition to reflect all of the changes introduced in C++ by the finalization of the C++ Standard, and also to reflect what I’ve learned since writing the first edition. The entire text present in the first edition has been examined and rewritten, sometimes removing old examples, often changing existing examples and adding new ones, and adding many new exercises. Significant rearrangement and re-ordering of the material took place to reflect the availability of better tools and my improved understanding of how people learn C++. A new chapter was added which is a rapid introduction to the C concepts and basic C++ features for those who don’t have the C background to tackle the rest of the book. The CD ROM bound into the back of the book contains a seminar that is an even gentler introduction to the C concepts necessary to understand C++ (or Java). It was created by Chuck Allison for my company (MindView, Inc.), and it’s called “Thinking in C: Foundations for Java and C++.” It introduces you to the aspects of C that are necessary for you to move on to C++ or Java, leaving out the nasty bits that C programmers must deal with on a day-to-day basis but that the C++ and Java languages steer you away from (or even eliminate, in the case of Java).

So the short answer to the question “what’s different in the 2nd edition?” is: what isn’t brand new has been rewritten, sometimes to the point where you wouldn’t recognize the original examples and material.


Learning C++

I clawed my way into C++ from exactly the same position I expect many of the readers of this book are in: as a programmer with a very no-nonsense, nuts-and-bolts attitude about programming. Worse, my background and experience was in hardware-level embedded programming, in which C has often been considered a high-level language and an inefficient overkill for pushing bits around. I discovered later that I wasn’t even a very good C programmer, hiding my ignorance of structures, malloc( ) and free( ), setjmp( ) and longjmp( ), and other “sophisticated” concepts, scuttling away in shame when the subjects came up in conversation instead of reaching out for new knowledge.

When I began my struggle to understand C++, the only decent book was Bjarne Stroustrup’s self-professed “expert’s guide,[1]” so I was left to simplify the basic concepts on my own. This resulted in my first C++ book,[2] which was essentially a brain dump of my experience. That was designed as a reader’s guide to bring programmers into C and C++ at the same time. Both editions[3] of the book garnered enthusiastic response.

At about the same time that Using C++ came out, I began teaching the language in seminars and presentations. Teaching C++ (and later, Java) became my profession; I’ve seen nodding heads, blank faces, and puzzled expressions in audiences all over the world since 1989. As I began giving in-house training to smaller groups of people, I discovered something during the exercises. Even those people who were smiling and nodding were confused about many issues. I found out, by creating and chairing the C++ and Java tracks at the Software Development Conference for many years, that I and other speakers tended to give the typical audience too many topics, too fast. So eventually, through both variety in the audience level and the way that I presented the material, I would end up losing some portion of the audience. Maybe it’s asking too much, but because I am one of those people resistant to traditional lecturing (and for most people, I believe, such resistance results from boredom), I wanted to try to keep everyone up to speed.

For a time, I was creating a number of different presentations in fairly short order. Thus, I ended up learning by experiment and iteration (a technique that also works well in C++ program design). Eventually I developed a course using everything I had learned from my teaching experience. It tackles the learning problem in discrete, easy-to-digest steps and for a hands-on seminar (the ideal learning situation) there are exercises following each of the presentations. You can find out about my public seminars at www.BruceEckel.com, and you can also learn about the seminars that I’ve turned into CD ROMs.

The first edition of this book developed over the course of two years, and the material in this book has been road-tested in many forms in many different seminars. The feedback that I’ve gotten from each seminar has helped me change and refocus the material until I feel it works well as a teaching medium. But it isn’t just a seminar handout; I tried to pack as much information as I could within these pages, and structure it to draw you through onto the next subject. More than anything, the book is designed to serve the solitary reader who is struggling with a new programming language.

Goals

My goals in this book are to:

  1. Present the material one simple step at a time, so the reader can easily digest each concept before moving on.
  2. Use examples that are as simple and short as possible. This often prevents me from tackling “real world” problems, but I’ve found that beginners are usually happier when they can understand every detail of an example rather than being impressed by the scope of the problem it solves. Also, there’s a severe limit to the amount of code that can be absorbed in a classroom situation. For this I sometimes receive criticism for using “toy examples,” but I’m willing to accept that in favor of producing something pedagogically useful.
  3. Carefully sequence the presentation of features so that you aren’t seeing something you haven’t been exposed to. Of course, this isn’t always possible; in those situations, a brief introductory description will be given.
  4. Give you what I think is important for you to understand about the language, rather than everything that I know. I believe there is an “information importance hierarchy,” and there are some facts that 95 percent of programmers will never need to know and that would just confuse them and add to their perception of the complexity of the language. To take an example from C, if you memorize the operator precedence table (I never did), you can write clever code. But if you have to think about it, it will confuse the reader/maintainer of that code. So forget about precedence, and use parentheses when things aren’t clear. This same attitude will be taken with some information in the C++ language, which I think is more important for compiler writers than for programmers.
  5. Keep each section focused enough so the lecture time – and the time between exercise periods – is reasonable. Not only does this keep the audience’s minds more active and involved during a hands-on seminar, it gives the reader a greater sense of accomplishment.
  6. Provide readers with a solid foundation so they can understand the issues well enough to move on to more difficult coursework and books (in particular, Volume 2 of this book).
  7. I’ve tried not to use any particular vendor’s version of C++ because, for learning the language, I don’t think that the details of a particular implementation are as important as the language itself. Most vendors’ documentation concerning their own implementation specifics is adequate.

Chapters

C++ is a language in which new and different features are built on top of an existing syntax. (Because of this, it is referred to as a hybrid object-oriented programming language.) As more people pass through the learning curve, we’ve begun to get a feel for the way programmers move through the stages of the C++ language features. Because it appears to be the natural progression of the procedurally-trained mind, I decided to understand and follow this same path and accelerate the process by posing and answering the questions that came to me as I learned the language and those questions that came from audiences as I taught the language.

This course was designed with one thing in mind: to streamline the process of learning C++. Audience feedback helped me understand which parts were difficult and needed extra illumination. In the areas in which I got ambitious and included too many features all at once, I came to know – through the process of presenting the material – that if you include a lot of new features, you have to explain them all, and the student’s confusion is easily compounded. As a result, I’ve taken a great deal of trouble to introduce the features as few at a time as possible; ideally, only one major concept at a time per chapter.

The goal, then, is for each chapter to teach a single concept, or a small group of associated concepts, in such a way that no additional features are relied upon. That way you can digest each piece in the context of your current knowledge before moving on. To accomplish this, I leave some C features in place for longer than I would prefer. The benefit is that you will not be confused by seeing all the C++ features used before they are explained, so your introduction to the language will be gentle and will mirror the way you will assimilate the features if left to your own devices.

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

Chapter 1: Introduction to Objects. When projects became too big and complicated to easily maintain, the “software crisis” was born, with programmers saying, “We can’t get projects done, and if we can, they’re too expensive!” This precipitated a number of responses, which are discussed in this chapter along with the ideas of object-oriented programming (OOP) and how it attempts to solve the software crisis. The chapter walks you through the basic concepts and features of OOP and also introduces the analysis and design process. In addition, you’ll learn about the benefits and concerns of adopting the language and suggestions for moving into the world of C++.

Chapter 2: Making and Using Objects. This chapter explains the process of building programs using compilers and libraries. It introduces the first C++ program in the book and shows how programs are constructed and compiled. Then some of the basic libraries of objects available in Standard C++ are introduced. By the time you finish this chapter you’ll have a good grasp of what it means to write a C++ program using off-the-shelf object libraries.

Chapter 3: The C in C++. This chapter is a dense overview of the features in C that are used in C++, as well as a number of basic features that are available only in C++. It also introduces the “make” utility that’s common in the software development world and that is used to build all the examples in this book (the source code for the book, which is available at www.BruceEckel.com, contains makefiles for each chapter). Chapter 3 assumes that you have a solid grounding in some procedural programming language like Pascal, C, or even some flavors of Basic (as long as you’ve written plenty of code in that language, especially functions). If you find this chapter a bit too much, you should first go through the Thinking in C seminar on the CD that’s bound with this book (and also available at www.BruceEckel.com).

Chapter 4: Data Abstraction. Most features in C++ revolve around the ability to create new data types. Not only does this provide superior code organization, but it lays the groundwork for more powerful OOP abilities. You’ll see how this idea is facilitated by the simple act of putting functions inside structures, the details of how to do it, and what kind of code it creates. You’ll also learn the best way to organize your code into header files and implementation files.

Chapter 5: Hiding the Implementation. You can decide that some of the data and functions in your structure are unavailable to the user of the new type by making them private. This means that you can separate the underlying implementation from the interface that the client programmer sees, and thus allow that implementation to be easily changed without affecting client code. The keyword class is also introduced as a fancier way to describe a new data type, and the meaning of the word “object” is demystified (it’s a fancy variable).

Chapter 6: Initialization and Cleanup. One of the most common C errors results from uninitialized variables. The constructor in C++ allows you to guarantee that variables of your new data type (“objects of your class”) will always be initialized properly. If your objects also require some sort of cleanup, you can guarantee that this cleanup will always happen with the C++ destructor.

Chapter 7: Function Overloading and Default Arguments. C++ is intended to help you build big, complex projects. While doing this, you may bring in multiple libraries that use the same function name, and you may also choose to use the same name with different meanings within a single library. C++ makes this easy with function overloading, which allows you to reuse the same function name as long as the argument lists are different. Default arguments allow you to call the same function in different ways by automatically providing default values for some of your arguments.

Chapter 8: Constants. This chapter covers the const and volatile keywords, which have additional meaning in C++, especially inside classes. You’ll learn what it means to apply const to a pointer definition. The chapter also shows how the meaning of const varies when used inside and outside of classes and how to create compile-time constants inside classes.

Chapter 9: Inline Functions. Preprocessor macros eliminate function call overhead, but the preprocessor also eliminates valuable C++ type checking. The inline function gives you all the benefits of a preprocessor macro plus all of the benefits of a real function call. This chapter thoroughly explores the implementation and use of inline functions.

Chapter 10: Name Control. Creating names is a fundamental activity in programming, and when a project gets large, the number of names can be overwhelming. C++ allows you a great deal of control over names in terms of their creation, visibility, placement of storage, and linkage. This chapter shows how names are controlled in C++ using two techniques. First, the static keyword is used to control visibility and linkage, and its special meaning with classes is explored. A far more useful technique for controlling names at the global scope is C++’s namespace feature, which allows you to break up the global name space into distinct regions.

Chapter 11: References and the Copy-Constructor. C++ pointers work like C pointers with the additional benefit of stronger C++ type checking. C++ also provides an additional way to handle addresses: from Algol and Pascal, C++ lifts the reference, which lets the compiler handle the address manipulation while you use ordinary notation. You’ll also meet the copy-constructor, which controls the way objects are passed into and out of functions by value. Finally, the C++ pointer-to-member is illuminated.

Chapter 12: Operator Overloading. This feature is sometimes called “syntactic sugar;” it lets you sweeten the syntax for using your type by allowing operators as well as function calls. In this chapter you’ll learn that operator overloading is just a different type of function call and you’ll learn how to write your own, dealing with the sometimes-confusing uses of arguments, return types, and the decision of whether to make an operator a member or friend.

Chapter 13: Dynamic Object Creation. How many planes will an air-traffic system need to manage? How many shapes will a CAD system require? In the general programming problem, you can’t know the quantity, lifetime, or type of objects needed by your running program. In this chapter, you’ll learn how C++’s new and delete elegantly solve this problem by safely creating objects on the heap. You’ll also see how new and delete can be overloaded in a variety of ways so you can control how storage is allocated and released.

Chapter 14: Inheritance and Composition. Data abstraction allows you to create new types from scratch, but with composition and inheritance, you can create new types from existing types. With composition, you assemble a new type using other types as pieces, and with inheritance, you create a more specific version of an existing type. In this chapter you’ll learn the syntax, how to redefine functions, and the importance of construction and destruction for inheritance and composition.

Chapter 15: Polymorphism and virtual Functions. On your own, you might take nine months to discover and understand this cornerstone of OOP. Through small, simple examples, you’ll see how to create a family of types with inheritance and manipulate objects in that family through their common base class. The virtual keyword allows you to treat all objects in this family generically, which means that the bulk of your code doesn’t rely on specific type information. This makes your programs extensible, so building programs and code maintenance is easier and cheaper.

Chapter 16: Introduction to Templates. Inheritance and composition allow you to reuse object code, but that doesn’t solve all of your reuse needs. Templates allow you to reuse source code by providing the compiler with a way to substitute type names in the body of a class or function. This supports the use of container class libraries, which are important tools for the rapid, robust development of object-oriented programs (the Standard C++ Library includes a significant library of container classes). This chapter gives you a thorough grounding in this essential subject.

Additional topics (and more advanced subjects) are available in Volume 2 of this book, which can be downloaded from the Web site www.BruceEckel.com.


Language standards

Throughout this book, when referring to conformance to the ISO C standard, I will generally just say ‘C.’ Only if it is necessary to distinguish between Standard C and older, pre-Standard versions of C will I make a distinction.

At this writing the C++ Standards Committee was finished working on the language. Thus, I will use the term Standard C++ to refer to the standardized language. If I simply refer to C++ you should assume I mean “Standard C++.”

There is some confusion over the actual name of the C++ Standards Committee and the name of the standard itself. Steve Clamage, the committee chair, clarified this:

There are two C++ standardization committees: The NCITS (formerly X3) J16 committee and the ISO JTC1/SC22/WG14 committee. ANSI charters NCITS to create technical committees for developing American national standards.

J16 was chartered in 1989 to create an American standard for C++. In about 1991 WG14 was chartered to create an international standard. The J16 project was converted to a "Type I" (International) project and subordinated to the ISO standardization effort.

The two committees meet at the same time at the same location, and the J16 vote constitutes the American vote on WG14. WG14 delegates technical work to J16. WG14 votes on the technical work of J16.

The C++ standard was originally created as an ISO standard. ANSI later voted (as recommended by J16) to adopt the ISO C++ standard as the American standard for C++.

Thus, ‘ISO’ is the correct way to refer to the C++ Standard.

Language support

Your compiler may not support all of the features discussed in this book, especially if you don’t have the newest version of the compiler. Implementing a language like C++ is a Herculean task, and you can expect that the features will appear in pieces rather than all at once. But if you attempt one of the examples in the book and get a lot of errors from the compiler, it’s not necessarily a bug in the code or the compiler; it may simply not be implemented in your particular compiler yet.



[1] Bjarne Stroustrup, The C++ Programming Language, Addison-Wesley, 1986 (first edition).

[2] Using C++, Osborne/McGraw-Hill 1989.

[3] Using C++ and C++ Inside & Out, Osborne/McGraw-Hill 1993.

[ Previous Chapter ] [ Table of Contents ] [ Index ] [ Next Chapter ]
Last Update:02/11/2007