Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Professional C++ [eng].pdf
Скачиваний:
284
Добавлен:
16.08.2013
Размер:
11.09 Mб
Скачать

Conquering Debugging

Lessons from the ArticleCitations Example

You might be inclined to disregard this example as too small to be representative of real debugging. Although the buggy code is not lengthy, many classes that you write will not be much bigger, even in large projects. Thus, this example corroborates the message from Chapter 19 about the importance of unit testing. Imagine if you had failed to test this example thoroughly before integrating it with the rest of the project. If these bugs showed up later, you and other engineers would have to spend more time narrowing down the problem before you could debug it as shown here. Additionally, the techniques shown in this example apply to all debugging, large scale or small.

Summar y

The most important concept in this chapter was the Fundamental Law of Debugging: avoid bugs when you’re coding, but plan for bugs in your code. The reality of programming is that bugs will appear. If you’ve prepared your program properly, with error logging, debug traces in a ring buffer, and asserts, then the actual debugging will be significantly easier.

In addition to these techniques, this chapter also presented specific approaches for debugging bugs. The most important rule when actually debugging is to reproduce the problem. Then, you can use cout debugging or a symbolic debugger to track down the root cause. Memory errors present particular difficulties, and account for the majority of bugs in C++ code. This chapter described the various categories of memory bugs and their symptoms, and showed several examples of debugging errors in a program.

559

Delving into the STL: Containers and Iterators

Many programmers who claim to know C++ have never heard of the standard template library. As a Professional C++ programmer, it behooves you to familiarize yourself with its powerful capabilities. You can save yourself immeasurable time and energy by incorporating the STL containers and algorithms into your programs instead of writing and debugging your own versions. Now that you have read Chapters 1 through 20, and are an expert C++ designer, coder, tester, and debugger, it’s time to master the STL.

Chapter 4 introduced the STL, described its basic philosophy and provided an overview of the various containers and algorithms. You should be familiar with that section of Chapter 4, as well as the content of most of the Chapters in Parts II and III, specifically Chapter 11 and Chapter 16.

This chapter begins a three-part tour of the STL by covering the STL containers, including:

Containers Overview: requirements on elements, general error handling, and iterators.

Sequential Containers: vector, deque, and list.

Container Adapters: queue, priority_queue, and stack.

Associative Containers: the pair utility, map, multimap, set, and multiset.

Other Containers: arrays, strings, streams, and bitset.

Chapter 22 continues the STL by describing and showing examples of the generic algorithms that you can use on container elements. The chapter also describes the predefined function object classes in the STL and shows you how to use them effectively as callbacks with the algorithms.

Chapter 23 examines some advanced aspects of STL programming with a focus on customizing and extending the library. It covers using and writing allocators, using iterator adapters, writing algorithms, writing containers, and writing iterators.

Chapter 21

Despite the depth of material found in this chapter and the next two, the standard template library is too large for this book to cover exhaustively. The resource material on the Web site contain a reference for the most useful parts of the standard library. Standard Library Header Files provides a summary of all the header files in the standard library, while the Standard Library Reference presents a reference for the various classes and algorithms in the STL. You should read Chapters 21 to 23 to learn about the STL, but keep in mind that they don’t mention every method and member that the various classes provide, or show you the prototypes of every algorithm. Consult the appendices for those details.

Containers Over view

Recall from Chapter 4 that the containers in the STL are generic data structures useful for storing collections of data. You should rarely need to use a C-style array, write a linked list, or design a stack when you use the STL. The containers are implemented as templates, which allows you to instantiate them for any type that meets certain basic conditions outlined below.

The STL provides 11 containers, divided into four categories. The sequential containers include the vector (dynamic array), list, and deque. The associative containers include the map, multimap, set, and multiset. The container adapters include the queue, priority_queue, and stack. The final container, the bitset, is in a class of its own. Additionally, C-style arrays, C++ strings, and streams all can be used as STL containers to a certain degree.

There is some debate about exactly which containers in C++ qualify as being part of the STL. This book is somewhat more inclusive in its definition than are others. Some people feel that only the sequential and associative containers qualify. Others allow strings, but not bitset and container adapters.

In our experience, the containers are the most valuable part of the STL (although some C++ aficionados find that statement heretical.) If you don’t have much time or interest to pursue the STL in detail, at least consider learning about the containers. Once you get past a few syntax details, they are not difficult to use, and will save you debugging time down the road.

Everything in the STL is in the std namespace. The examples in this book usually use the blanket using namespace std; statement in source files, but you can be more selective in your own programs about which symbols from std to use.

Requirements on Elements

STL containers use value semantics on elements. That is, they store a copy of the element that they are given, and return copies of elements when requested. They also assign to elements with the assignment operator and destroy elements with the destructor. Thus, when you write classes that you intend to use with the STL, make sure that it’s okay to have multiple copies of an object in the program at the same time.

If you prefer reference semantics, you must implement them yourself by storing pointers to elements instead of the elements themselves. When the containers copy a pointer, the result still refers to the same element.

562