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», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

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

Интервал:

Закладка:

Сделать

Matching an exception doesn’t require a perfect correlation between the exception and its handler. An object or reference to a derived-class object will match a handler for the base class. (However, if the handler is for an object rather than a reference, the exception object is "sliced"— truncated to the base type — as it is passed to the handler; this does no damage but loses all the derived-type information.) For this reason, as well as to avoid making yet another copy of the exception object, it is always better to catch an exception by reference instead of by value [3] In fact, you might want to always specify exception objects by const reference in exception handlers. It’s very rare to modify and rethrow an exception. We are not dogmatic about this practice however. . If a pointer is thrown, the usual standard pointer conversions are used to match the exception. However, no automatic type conversions are used to convert from one exception type to another in the process of matching, for example: .

//: C01:Autoexcp.cpp

// No matching conversions

#include

using namespace std;

class Except1 {};

class Except2 {

public:

Except2(const Except1&) {}

};

void f() { throw Except1(); }

int main() {

try { f();

} catch (Except2&) {

cout << "inside catch(Except2)" << endl;

} catch (Except1&) {

cout << "inside catch(Except1)" << endl;

}

} ///:~

Even though you might think the first handler could be used by converting an Except1object into an Except2using the constructor conversion, the system will not perform such a conversion during exception handling, and you’ll end up at the Except1handler .

The following example shows how a base-class handler can catch a derived-class exception: .

//: C01:Basexcpt.cpp

// Exception hierarchies

#include

using namespace std;

class X {

public:

class Trouble {};

class Small : public Trouble {};

class Big : public Trouble {};

void f() { throw Big(); }

};

int main() {

X x;

try {

x.f();

} catch(X::Trouble&) {

cout << "caught Trouble" << endl;

// Hidden by previous handler:

} catch(X::Small&) {

cout << "caught Small Trouble" << endl;

} catch(X::Big&) {

cout << "caught Big Trouble" << endl;

}

} ///:~

Here, the exception-handling mechanism will always match a Troubleobject, or anything that is a Trouble(through public inheritance), [4] Only unambiguous, accessible base classes can catch derived exceptions. This rule minimizes the runtime overhead needed to validate exceptions. Remember that exceptions are checked at runtime, not at compile time, and therefore the extensive information available at compile time is not available during exception handling to the first handler. That means the second and third handlers are never called because the first one captures them all. It makes more sense to catch the derived types first and put the base type at the end to catch anything less specific .

Notice that these examples catch exceptions by reference, although for these classes it isn’t important because there are no additional members in the derived classes, and there are no argument identifiers in the handlers anyway. You’ll usually want to use reference arguments rather than value arguments in your handlers to avoid slicing off information .

Catching any exception

Sometimes you want to create a handler that catches any type of exception. You do this using the ellipsis in the argument list: .

Catch(...) {

cout << "an exception was thrown" << endl;

}

An ellipsis catches any exception, so you’ll want to put it at the end of your list of handlers to avoid pre-empting any that follow it .

Because the ellipsis gives you no possibility to have an argument, you can’t know anything about the exception or its type. It’s a "catchall." Such a catchclause is often used to clean up some resources and then rethrow the exception .

Re-throwing an exception

You usually want to re-throw an exception when you have some resource that needs to be released, such as a network connection or heap memory that needs to be deallocated. (See the section "Resource Management" later in this chapter for more detail). If an exception occurs, you don’t necessarily care what error caused the exception—you just want to close the connection you opened previously. After that, you’ll want to let some other context closer to the user (that is, higher up in the call chain) handle the exception. In this case the ellipsis specification is just what you want. You want to catch any exception, clean up your resource, and then re-throw the exception so that it can be handled elsewhere. You re-throw an exception by using throwwith no argument inside a handler: .

catch(...) {

cout << "an exception was thrown" << endl;

// Deallocate your resource here, and then re-throw…

throw;

}

Any further catchclauses for the same tryblock are still ignored—the throwcauses the exception to go to the exception handlers in the next-higher context. In addition, everything about the exception object is preserved, so the handler at the higher context that catches the specific exception type can extract any information the object may contain .

Uncaught exceptions

As we explained in the beginning of this chapter, exception handling is considered better than the traditional return-an-error-code technique because exceptions can’t be ignored. If none of the exception handlers following a particular tryblock matches an exception, that exception moves to the next-higher context, that is, the function or tryblock surrounding the tryblock that did not catch the exception. (The location of this tryblock is not always obvious at first glance, since it’s higher up in the call chain.) This process continues until, at some level, a handler matches the exception. At that point, the exception is considered "caught," and no further searching occurs .

The terminate( ) function

If no handler at any level catches the exception, the special library function terminate( )(declared in the header) is automatically called. By default, terminate( )calls the Standard C library function abort( ), which abruptly exits the program. On Unix systems, abort( )also causes a core dump. When abort( )is called, no calls to normal program termination functions occur, which means that destructors for global and static objects do not execute. The terminate( )function also executes if a destructor for a local object throws an exception during stack unwinding (interrupting the exception that was in progress) or if a global or static object’s constructor or destructor throws an exception. In general, do not allow a destructor to throw an exception .

The set_terminate( ) function

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

Интервал:

Закладка:

Сделать

Похожие книги на «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