обработка ошибок — самый простой способ завершить функцию в переполнении стека

Мне интересно, какой самый простой или самый удобный способ завершить функцию в C ++.

Например у меня int function() и я хочу, чтобы он ничего не делал (что-то вроде void) при определенных условиях в функции, но я не хочу, чтобы вся программа заканчивалась. Так что, не «выход», пожалуйста: D.

Я видел, как люди используют return;, но я не уверен, что это безопасно.

Надеюсь, ты сможешь мне помочь. Спасибо!

1

Решение

Да, с return ты можешь вернуться?

Или ты мог throw исключение.

В обоих случаях вы должны знать, как обрабатывать необходимые ресурсы.

3

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

Вам необходимо либо указать возвращаемое значение, либо throw исключение. Если поток управления возвращается к вызывающей стороне как обычно, то просто return 0;, Но это наводит на мысль об организационной проблеме.

return без значения допускается только для функций, возвращающих void,

3

Внутри объявленной функции int function() Вы всегда можете вернуть некоторое значение, например с return 0; -в любое время и в любом месте внутри функционального органа.

Вы также можете выйти за пределы функции, бросив исключение, это нелокальный поток управления перечислить.

На практике вы бросаете какое-то исключение, например,

 throw std::runtime_error("something bad");

тогда какая-то функция все еще активна в стек вызовов должен catch это исключение. Так что, возможно, ваш main содержит

 try {
do_the_job(something);
}
catch (std::runtime_error err) {
std::cerr << "bad thing happened:" << err.what() << std::endl;
exit(EXIT_FAILURE);
}

а также do_the_job называется foo который называется bar который назвал ваш function который throw исключение, которое попадает в mainи т. д. (деструкторы локальных значений в стеке вызовов вызываются).

3

В C ++ есть три способа завершения функции:

  • return подходящее значение
  • throw исключение
  • std::terminate программа

Вам, программисту, решать, как справиться с ситуацией, в которой вы находитесь. В общем, вы попадаете в две ситуации:

  • техническая ошибка: поврежденное состояние, нарушение предварительных условий, как правило, обрабатывается путем вызова std::terminate или же throw
  • функциональная ситуация: с учетом аргумента, нет результата (например, search может потерпеть неудачу), обычно обрабатывается любым throw или возвращение дозорного значения.

Итак, поскольку в вашем случае мы говорим о функциональной ситуации, вы можете спросить себя, является ли эта ситуация ошибка со стороны вызывающего абонента (в этом случае исключение является хорошим кандидатом) или, если это нормальная ситуация (например, search ничего не находя) в этом случае значение дозорного, вероятно, будет лучшим.

Для дозорных значений я видел несколько методов:

  • C-ish: вернуть указатель (и использовать nullptr как Sentinel), при необходимости может быть умным указателем
  • Object-ish: иметь объект Null такого типа
  • Булева глупость: возьмите «аргумент возврата» по ссылке и верните логическое значение, чтобы указать, написали ли вы в него или нет
  • Функциональный иш: вернуть boost::optional<Type> (и использовать boost::none как Страж)

Есть действительно много схем на выбор; Я бы порекомендовал последнее, если вы возвращаете копию и указатель, если вы возвращаете дескриптор ранее существовавшего объекта.

3

Если ваша функция имеет тип возвращаемого значения intтогда, если вы вообще вернетесь, вам нужно будет вернуть значение, а не просто return;,

Возвращаемое значение вашей функции, вероятно, имеет некоторое значение для вызывающей стороны. Таким образом, применяется одна из трех ситуаций:

1) Доступно целое число, которое не означает «я что-то сделал». Таким образом, вы можете задокументировать, что значение означает «Я ничего не делал», и вернуть его. 0 а также -1 Как правило, это значения, которые наиболее вероятно будут использоваться для этого, но это полностью зависит от того, что делает функция и что означает возвращаемое значение.

2) Нет доступных значений, которые не означают «Я что-то сделал», поэтому функция не может вернуть значение, чтобы сказать «Я ничего не сделал». Затем вы можете изменить сигнатуру функции, чтобы дать ей возможность указать, что она что-то сделала — например, вернуть pair<bool,int> вместо просто intс одним значением, указывающим на успех / неудачу, и другим, которое имеет значение при успехе, но не при неудаче. Или вы можете добавить int & параметр для function в котором вы будете хранить значение, используемое в настоящее время в качестве возвращаемого значения, и измените тип возвращаемого значения на bool что просто указывает на успех или неудачу. В качестве альтернативы, если речь идет о ситуации, когда функция не может выполнить операцию, для которой она предназначена, вы можете вызвать исключение (и задокументировать, что может вызвать функция).

В обоих вышеупомянутых случаях, возможно, придется обновить существующий код, который вызывает функцию (и, конечно, будет, если вы измените подпись). Это приводит к третьей ситуации:

3) нет возможности для функции указать, что она ничего не сделала, а также вам не разрешено менять интерфейс функции (например, возможно, уже задокументировано, что она не выдается, и вы не хотите менять факт, на который полагаются существующие вызывающие абоненты). Тогда я боюсь, что ты в ситуации, которую ты не хотел. Если функция обнаруживает, что она не может выполнить свои договорные обязательства, даже бросая, то все, что вы можете сделать, это terminate или же exit, Программа не может продолжаться, потому что вызывающая сторона имеет полное право ожидать, что функция сделает «что-то», но вы не можете этого сделать. Это обычно указывает на то, что дизайн каким-то образом неправильный или что вы реализуете интерфейс, который недостаточно гибок для поддержки того, что вы планируете.

3

Просто используя return Это может привести к некоторым неприятностям, поскольку компилятор требует, чтобы вы действительно возвращали значение, и любой разумный человек мог бы ожидать этого при чтении вашего прототипа. Лучший подход для вашего случая будет throw исключение.

РЕДАКТИРОВАТЬ: Мне напомнили ниже, что да, исключения должны создаваться только в случае неисправимой ошибки. Возможно простой return это самый быстрый подход. Но правильное поведение, которое вы должны иметь, это поднять какой-либо флаг ошибки, когда ваше условие выполнено.

2
По вопросам рекламы [email protected]