Bruce Eckel - Thinking In C++. Volume 2 - Practical Programming

Здесь есть возможность читать онлайн «Bruce Eckel - Thinking In C++. Volume 2 - Practical Programming» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Год выпуска: 2003, ISBN: 2003, Издательство: Prentice Hall, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Thinking In C++. Volume 2: Practical Programming: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Thinking In C++. Volume 2: Practical Programming»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Best selling author Bruce Eckel has joined forces with Chuck Allison to write
, the sequel to the highly received and best selling
. Eckel is the master of teaching professional programmers how to quickly learn cutting edge topics in C++ that are glossed over in other C++ books. In
, the authors cover the finer points of exception handling, defensive programming and string and stream processing that every C++ programmer needs to know. Special attention is given to generic programming where the authors reveal little known techniques for effectively using the Standard Template Library. In addition, Eckel and Allison demonstrate how to apply RTTI, design patterns and concurrent programming techniques to improve the quality of industrial strength C++ applications. This book is targeted at programmers of all levels of experience who want to master C++.

Thinking In C++. Volume 2: Practical Programming — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Thinking In C++. Volume 2: Practical Programming», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

return EXIT_SUCCESS;

} ///:~

The violation of the invariant is easily detected with the condition if (low > high), because if the user always tells the truth, we will always find the secret number before we run out of numbers to guess from. (See the last paragraph of the text that follows the program extractCode.cppat the end of Chapter 3 for an explanation of the macros EXIT_FAILUREand EXIT_SUCCESS) .

Assertions

The condition in the Hi-lo program depends on user input, so you’re powerless to always prevent a violation of the invariant. Most often, however, invariants depend only on the code you write, so they will always hold, if you’ve implemented your design correctly. In this case, it is clearer to make an assertion , which is a positive statement that reveals your design decisions .

For example, suppose you are implementing a vector of integers, which, as you know, is an expandable array that grows on demand. The function that adds an element to the vector must first verify that there is an open slot in the underlying array that holds the elements; otherwise, it needs to request more heap space and copy the existing elements to the new space before adding the new element (and of course deleting the old array). Such a function might look like the following: .

void MyVector::push_back(int x) {

if (nextSlot == capacity)

grow();

assert(nextSlot < capacity);

data[nextSlot++] = x;

}

In this example, datais a dynamic array of ints with capacityslots and nextSlotslots in use. The purpose of grow( )is to expand the size of dataso that the new value of capacityis strictly greater than nextSlot. Proper behavior of MyVectordepends on this design decision, and it will never fail if the rest of the supporting code is correct, so we assert the condition with the assert( )macro (defined in the header ) .

The Standard C library assert( )macro is brief, to the point, and portable. If the condition in its parameter evaluates to non-zero, execution continues uninterrupted; if it doesn’t, a message containing the text of the offending expression along with its source file name and line number is printed to the standard error channel and the program aborts. Is that too drastic? In practice, it is much more drastic to let execution continue when a basic design assumption has failed. Your program needs to be fixed .

If all goes well, you will have thoroughly tested your code with all assertions intact by the time the final product is deployed. (We’ll say more about testing later.) Depending on the nature of your application, the machine cycles needed to test all assertions at runtime might be too much of a performance hit in the field. If that’s the case, you can remove all the assertion code automatically by defining the macro NDEBUGand rebuilding the application .

To see how this works, note that a typical implementation of assert( )looks something like this:

#ifdef NDEBUG

#define assert(cond) ((void)0)

#else

void assertImpl(const char*, const char*, long);

#define assert(cond) \

((cond) ? (void)0 : assertImpl(???))

#endif

When the macro NDEBUGis defined, the code decays to the expression (void) 0, so all that’s left in the compilation stream is an essentially empty statement as a result of the semicolon you appended to each assert( )invocation. If NDEBUGis not defined, assert(cond)expands to a conditional statement that, when condis zero, calls a compiler-dependent function (which we named assertImpl( )) with a string argument representing the text of cond, along with the file name and line number where the assertion appeared. (We used "???" as a place holder in the example, but the string mentioned is actually computed there, along with the file name and the line number where the macro occurs in that file. How these values are obtained is immaterial to our discussion.) If you want to turn assertions on and off at different points in your program, you not only have to #defineor #undef NDEBUG, but you have to re-include . Macros are evaluated as the preprocessor encounters them and therefore use whatever NDEBUGstate applies at that point in time. The most common way to define NDEBUGonce for an entire program is as a compiler option, whether through project settings in your visual environment or via the command line, as in

mycc –DNDEBUG myfile.cpp

Most compilers use the – Dflag to define macro names. (Substitute the name of your compiler’s executable for myccabove.) The advantage of this approach is that you can leave your assertions in the source code as an invaluable bit of documentation, and yet there is no runtime penalty. Because the code in an assertion disappears when NDEBUGis defined, it is important that you never do work in an assertion . Only test conditions that do not change the state of your program .

Whether using NDEBUGfor released code is a good idea remains a subject of debate. Tony Hoare, one of the most influential computer scientists of all time, [13] Among other things he invented Quicksort. has suggested that turning off runtime checks such as assertions is similar to a sailing enthusiast who wears a life jacket while training on land and then discards it when he actually goes to sea. [14] As quoted in Programming Language Pragmatics , by Michael L. Scott, Morgan-Kaufmann, 2000. If an assertion fails in production, you have a problem much worse than degradation in performance, so choose wisely .

Not all conditions should be enforced by assertions, of course. User errors and runtime resource failures should be signaled by throwing exceptions, as we explained in detail in Chapter 1. It is tempting to use assertions for most error conditions while roughing out code, with the intent to replace many of them later with robust exception handling. Like any other temptation, use caution, since you might forget to make all the necessary changes later. Remember: assertions are intended to verify design decisions that will only fail because of faulty programmer logic. The ideal is to solve all assertion violations during development. Don’t use assertions for conditions that aren’t totally in your control (for example, conditions that depend on user input). In particular, you wouldn’t want to use assertions to validate function arguments; throw a logic_errorinstead .

The use of assertions as a tool to ensure program correctness was formalized by Bertrand Meyer in his Design by Contract methodology. [15] See his book, Object-Oriented Software Construction , Prentice-Hall, 1994. Every function has an implicit contract with clients that, given certain pre-conditions , guarantees certain post-conditions . In other words, the pre-conditions are the requirements for using the function, such as supplying arguments within certain ranges, and the post-conditions are the results delivered by the function, either by return value or by side-effect .

What should you do when clients fail to give you valid input? They have broken the contract, and you need to let them know. As we mentioned earlier, this is not the best time to abort the program (although you’re justified in doing so since the contract was violated), but an exception is certainly in order. This is why the Standard C++ library throws exceptions derived from logic_error, such as out_of_range. [16] This is still an assertion conceptually , but since we don’t want to halt execution, the assert(В ) macro is not appropriate. Java 1.4, for example, throws an exception when an assertion fails. If there are functions that only you call, however, such as private functions in a class of your own design, the assert( )macro is appropriate, since you have total control over the situation and you certainly want to debug your code before shipping .

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Thinking In C++. Volume 2: Practical Programming»

Представляем Вашему вниманию похожие книги на «Thinking In C++. Volume 2: Practical Programming» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Thinking In C++. Volume 2: Practical Programming»

Обсуждение, отзывы о книге «Thinking In C++. Volume 2: Practical Programming» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x