Каковы альтернативы выбрасыванию исключения в C ++ - PullRequest
3 голосов
/ 22 сентября 2019

Я недавно взял интервью у компании для стажировки.Они попросили меня написать рекурсивную функцию для вычисления факториала заданного целого числа.Итак, я написал что-то вроде этого на бумаге:

int factorial(int n){
    if(n<0){throw std::invalid_argument( "received negative value" );}
    if(n == 0){return 1;}
    else{
        return n * factorial(n-1);
    }
}

Затем, в качестве продолжения, они задавали мне вопросы в духе

«Что лежит на исключениипоставить пользователя этой функции? "

" Можете ли вы справиться с этим любым другим способом? "

" Можете ли вы справиться с этим изящно? "

Iдействительно не знал, что они искали / намекали.Кто-нибудь может сказать мне, если я что-то здесь упускаю?

1 Ответ

3 голосов
/ 22 сентября 2019

Требование проверки исключения требует, чтобы вызывающий объект перехватывал и обрабатывал исключение, загромождая свой код, а также накладывая накладные расходы на обработку для обработки исключения.

Есть несколько других способов возврата без вызоваисключение.

  • Факториал числа не может быть нулевым или отрицательным, поэтому вы можете вернуть 0 или отрицательное целое число (то есть «магическое число»), чтобы указать, что факториал не существуетили не может быть найден.Аналогичным образом, если входное значение слишком велико для вычисления факториала в диапазоне int, вы также можете вернуть это недопустимое значение или установить конкретное значение, которое указывает на режим сбоя (например, 0 означает, что входное значение отрицательное, -1 означает, что ввод слишком велик, -2 означает любое другое исключение).
  • Вы можете изменить сигнатуру вашего метода, чтобы возвращать указатель на int, и установить логику для возврата NULL для указания отсутствия результата (код на языке C был классически заполнен логикой «проверка на нулевое значение после вызова, чтобы убедиться в успешности»).Если вы найдете факториал, верните указатель на int, содержащий это значение, созданное в куче, используя new.
  • . Вы можете принять short int в качестве входного параметра, исключив многие (но невсе) входные значения, факториал которых слишком велик, чтобы соответствовать возвращаемому значению.Это не все исправит, но каждый помогает.В сочетании с другим методом вы можете еще больше уменьшить потенциальные режимы отказа.

Первый вариант выше может быть изящным, поскольку он позволяет вызывающему абоненту потреблять значение во многих отношениях (например, распечатав его, используя его в дальнейшей математической операции), не вводя что-либо не числовое или не имея числа, с которым нужно иметь дело.Недостатком является то, что вы можете получить бессмысленное число.В некоторых контекстах лучше вывести «Количество этажей в здании: -1, стоимость: $ -1», чем разбиться прямо в середине важной демонстрации!Подобная ситуация (недопустимая с точки зрения бизнес-правил, но способная обрабатывать данные, в данном случае указатель) привела к известной ошибке Minus World в Super Mario Bros.!

Последнее значение еще более изящно, посколькуэто помогает предотвратить попадание недействительных данных даже в и в функцию.Как говорится, «Мусор на входе», «Мусор на выходе».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...