Обычно я бы сказал (1). Но если вы обнаружите, что все вызывающие объекты окружают конструкцию с помощью try / catch, вы можете также предоставить статическую вспомогательную функцию в (3), так как с небольшой подготовкой исключение может быть сделано невозможным.
Существует еще один вариант, хотя он имеет существенные последствия для стиля кодирования, поэтому его не следует воспринимать легкомысленно,
5) Не передавайте параметры в конструктор:
class Time
{
protected:
unsigned int m_hour;
unsigned int m_minute;
unsigned int m_second;
public:
Time() : m_hour(0), m_minute(0), m_second(0) {}
// either return success/failure, or return void but throw on error,
// depending on why the exception in constructor was undesirable.
bool Set(unsigned int hour, unsigned int minute, unsigned int second);
};
Это называется двухфазным построением и используется именно в ситуациях, когда конструкторам нежелательно или невозможно генерировать исключения. Код с использованием nothrow new, который должен быть скомпилирован с помощью -fno-exceptions
, вероятно, является классическим случаем Как только вы привыкаете к этому, это немного менее раздражает, чем вы могли подумать.
4.1 Квадратные корни Ньютона-Рафсона
Эти две строки
sqroot a0 eps n = within eps (iterate (next n) a0)
relativesqrt a0 eps n = relative eps (iterate (next n) a0)
почти идентичны, поэтому вы можете абстрагироваться на один шаг дальше:
sqroot method a0 eps n = method eps (iterate (next n) a0)
relativesqrt = sqroot relative
withinsqrt = sqroot within
4.2 Числовое дифференцирование
Я не делаю ' Я вижу смысл использования h0
в качестве аргумента функции дифференцирования
, поскольку это всего лишь отправная точка для предельной последовательности 0
. (То же самое не верно для a0
в случае Ньютона-Рапсона, где начальная точка может иметь значение.)
Я думаю, также уместно абстрагироваться от скорости, с которой этот предел приближается к нулю:
differentiate rate f x = map (easydiff f x) (iterate rate 1)
Конечно, можно сделать и то, и другое:
differentiate rate h0 f x = map (easydiff f x) (iterate rate h0)
В любом случае это довольно произвольное решение.
4.2 Интеграция
Вы можете использовать
zipWith (+) (integ f a m fa fm) (integ f m b fm fb)
вместо
map (uncurry (+)) (zip (integ f a m fa fm) (integ f m b fm fb))
, что, на мой взгляд, более читабельно.
1111035]
Для в
и родственник
Я бы использовал защищенную нотацию:
within eps (a:b:rest)
| abs(a-b)<=eps = b
| otherwise = within eps (b:rest)
Для секунды
вы можете написать !! 1
. Я полагаю, что последний вариант - это личное предпочтение.
Вы также должны указать сигнатуры типа.
Изменить : Если вы используете обфускацию, попробуйте:
within :: (Ord a, Num a) => a -> [a] -> a
within eps l@(_:xs) = snd. head . filter ((<= eps) . fst) $ zip zs xs
where
zs = zipWith (\ a b -> abs (a-b)) l xs
(Тип проверен, не проверено - и Я никогда не знаю, правильно ли я установил фильтр или его нужно отключить;)
Итак, это прямой перевод (т. Е. Старайтесь, чтобы код выглядел как можно более похожим) или встроенный (т. Е. Внесение в код как можно большего количества идиоматических настроек, не усложняя понимание примеров , конечно) один?
Предполагая, что этот "проект" все еще продолжается ......