Читаем Thinking In C++. Volume 2: Practical Programming полностью

There are two basic models in exception-handling theory: termination and resumption. In termination (which is what C++ supports), you assume the error is so critical that there’s no way to automatically resume execution at the point where the exception occurred. In other words, "whoever" threw the exception decided there was no way to salvage the situation, and they don’t want to come back.

The alternative error-handling model is called resumption, first introduced with the PL/I language in the 1960s[2].Using resumption semantics means that the exception handler is expected to do something to rectify the situation, and then the faulting code is automatically retried, presuming success the second time. If you want resumption in C++, you must explicitly transfer execution back to the code where the error occurred, usually by repeating the function call that sent you there in the first place. It is not unusual, therefore, to place your try block inside a while loop that keeps reentering the try block until the result is satisfactory.

Historically, programmers using operating systems that supported resumptive exception handling eventually ended up using termination-like code and skipping resumption. Although resumption sounds attractive at first, it seems it isn’t quite so useful in practice. One reason may be the distance that can occur between the exception and its handler; it is one thing to terminate to a handler that’s far away, but to jump to that handler and then back again may be too conceptually difficult for large systems on which the exception can be generated from many points.

<p>Exception matching</p>

When an exception is thrown, the exception-handling system looks through the "nearest" handlers in the order they appear in the source code. When it finds a match, the exception is considered handled and no further searching occurs.

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]. 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 Except1 object into an Except2 using the constructor conversion, the system will not perform such a conversion during exception handling, and you’ll end up at the Except1 handler.

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 Trouble object, or anything that is a Trouble (through public inheritance),[4] 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.

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных