Может ли обработка исключений объекта, чей конструктор генерирует исключение, быть рядом с его основанным на стеке созданием кода?

Я пытаюсь сделать мой код C ++ безопасным от исключений, и у меня возникла проблема, которая не поможет ни опросу друзей, ни поиску в Интернете.

Насколько я понимаю, когда создание объекта с помощью конструктора потенциально может вызвать исключение, код для создания должен быть заключен в try обработка блоков и исключений выполняется в catch(){},

Если создание основано на куче (например, newРедактор с распределителем по умолчанию), я могу разместить код обработки исключений рядом с созданием:

void f() {
// work unrelated to Hoge object here

try {
Hoge *pHoge = new Hoge(); // could throw an exception
} catch(HogeException& ex) {
// handle exception
}

// rest of work here
}

Однако, если создание основано на стеке, я не могу найти способы сделать это и прибегнуть к коду, как показано ниже, из-за объема try блок:

void g() {
// work unrelated to Hoge object here

try {
Hoge hoge; // could throw an exception

// rest of work here
} catch(HogeException& ex) {
// handle exception
}
}

Если // rest of work приведенный выше код является большим, расстояние между созданием объекта и обработкой исключений может быть большим, что снижает читабельность кода …

Я предпочитаю, чтобы код обработки исключений был близок к созданию объекта (и, возможно, это одна из концепций trycatch состав). Есть ли какие-то решения?

0

Решение

Делегировать // rest of work к вспомогательной функции и передать Hoge& к этой функции:

void RestOfWork(Hoge& hoge)
{
// rest of work here
}

void g() {
// work unrelated to Hoge object here

try {
Hoge hoge;
RestOfWork(hoge);
// rest of work here
} catch(HogeException& ex) {
// handle exception
}
}

Между прочим, Hoge hoge(); не делает то, что вы думаете, что делает. Вы, вероятно, думаете, что объявляете объект с именем hoge типа Hogeи инициализировать его, вызывая конструктор по умолчанию. Что вы на самом деле делаете, это объявляете функцию с именем hoge который не принимает параметров и возвращает Hoge по значению. Я исправил это в моем коде выше.

редактировать Действительно, как подсказывает @LightnessRacesInOrbit, конструкция Hoge Объект также может иметь место в функции отсрочки, например:

  void RestOfWork()
{
Hoge hoge;
// rest of work here
}

void g() {
// work unrelated to Hoge object here

try {
RestOfWork();
} catch(HogeException& ex) {
// handle exception
}
}
5

Другие решения

Разумный способ сделать это — использовать обнуляемый контейнер из одного элемента, например, boost::optional:

void g() {
// work unrelated to Hoge object here

boost::optional<Hoge> opt_hoge;
try {
opt_hoge = boost::in_place<Hoge>();
} catch(HogeException& ex) {
// handle exception
}
Hoge &hoge = *opt_hoge;

// rest of work here
}

Если вы не можете использовать Boost, std::unique_ptr будет работать за счет кучи распределения:

void g() {
// work unrelated to Hoge object here

std::unique_ptr<Hoge> opt_hoge;
try {
opt_hoge = std::unique_ptr<Hoge>(new Hoge);
} catch(HogeException& ex) {
// handle exception
}
Hoge &hoge = *opt_hoge;

// rest of work here
}
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector