![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
Есть класс, данными которого являются в том числе численные значения. Например есть некий параметр Х, который может принимать значения от 0 до 1. Есть некоторая функция, которая задает этот параметр, например SetX(double x). Всякий раз в подобных случаях я ломаю голову - где лучше проверять корректность данных - внутри функции SetX или же на стадии подготовки данных для этой функции, в данном случае это аргумент x. Казалось бы удобнее это делать вне класса, но иногда кажется что и внутри класса это уместно. Ведь если функцию SetX этим механизмом проверки корректности аргумента не снабдить, то можно ненароком этому параметру присвоить какое-то некорректное значение.
Это сообщение отредактировал(а) Нитонисе - 23.5.2013, 16:51 |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
внутри. так будет проверено каждое обращение функции.
и вне - так будет проверено значение, введенное пользователем, что даст возможность не отвалиться по исключению, возбужденному в SetX(), а повторно выполнить ввод. Добавлено через 1 минуту и 57 секунд во втором случае проверка должна быть не перед вызовом SetX(), а после получения значения. если это значение не ввод пользователя, а вычисленный результат, проверять его нужно, видимо, в точке принятия решения - передавать его дальше или нет, т.е. зависит от конкретного приложения. |
|||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
Если проверять аргумент х и на стадии его формирования и внутри функции - то это будет дублирование проверки. Разумно ли это?
|
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
внутри функции параметры проверяются на корректность для данной функции. А вне функции они проверяются на допустимость для данного алгоритма.
|
|||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
То есть если для некоторых вычислений, где используется этот параметр Х должен принимать значения от 0 до 1, то при выполнении функции SetX(double x) проверку аргумента надо производить перед вызовом функции? А в самой функции тогда остается просто SetX(double x){this->X = x};
|
|||
|
||||
| NoviceF |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
Считаю внутри функции нужно проводить в любом случае.. Сегодня ты проверяешь результаты снаружи, а завтра кто-то воспользуется твоим классом и начнёт туда записывать непонятно что. Класс должен сопротивляться при помощи ассертов, возвратов фолсов и выбрасывания исключений
|
|||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
А как насчет дублирования проверки в таком случае? |
|||
|
||||
| NoviceF |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
Если для класса this->X имеет смысл только при положительных значениях или в определённом диапазоне - это и нужно бы проверить, перед выполнением присваивания this->X = x. Вообще, если значимы только 0 или не ноль, логичнее было бы bool использовать. Добавлено через 1 минуту и 3 секунды Корректность работы намного предпочтительнее производительности в большинстве случаев. Добавлено через 12 минут и 22 секунды Когда функция одна, может и не совсем виден масштаб проблемы.. А если 4-5 функций последовательно вызывают друг друга и на пятой приложение падает.. а в процессе отладки выясняется, что проблема в аргументах переданных первой функции второй. По плану первая функция должна была всё правильно расчитать, но где-то закралась ошибка и результат её работы не может быть корректно обработан второй функцией.. И если во второй функции (и всех последующих) не делать проверку агрументов - ошибка лавиной пройдёт через весь маршрут. Ну, и если нет предположений о причине ошибки (а обычно у меня их нет |
|||
|
||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
Есть такое правило - если ф-ция public, то она должна проверять параметры, если private - нет.
Ессно, это - не догма, но я пользуюсь и мне так удобно -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| NoviceF |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
На мой взгляд, даже в приватных функциях, как минимум ассерты не повредят
Это сообщение отредактировал(а) NoviceF - 24.5.2013, 09:06 |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Смотри, квадратный корень можно брать от любого неотрицательного числа. Поэтому функция извлечения корня проверяет параметр на отрицательность. Если он отрицательный, то тогда выдает ошибку. Твой алгоритм считает сложную функцию. И на каком-то этапе перед извлечением корня ты проверяешь промежуточный результат (по идее, правильно проверять только входные параметры, но иногда для проверки необходимо проделать половину всех вычислений) на корректность. И не обязательно на неотрицательность. Вот именно это я и имел в виду. Смысл проверять перед функцией имеется только тогда, когда функция не может сигнализировать об ошибке. |
|||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
Да, именно. И мне кажется рациональнее проверять именно перед функцией, а не внутри нее. Одна из причин - если проверять внутри функции, то нужно разрабатывать систему сигнализирования о том что именно функции не понравилось. Например аргумент должен быть положительным и не больше единицы. Значит функция своим возвращаемым значением должна уметь сказать - "работа не сделана, аргумент отрицательный" или "работа не сделана, аргумент больше единицы". По идее этим возвращаемым из ункции значением может быть простой int. Например если вернули 1 - функция сработала как надо, вернули 2 - получили отрицательный аргумент и поэтому не обработали, вернули 3 - получили аргумент больше единицы и поэтому не обработали. Мне кажется такой подход чересчур громоздкий. Он может быть оправдан только если разрабатываемый класс будут использовать сторонние разработчики, которые могут и не знать какие проверки надо выполнять перед выполнением функции. Поэтому для них все проверки можно сразу в функцию зашить. А если только я использую этот класс и четко понимаю как надо его использовать, то такая внутренняя проверка может и не нужна. |
|||
|
||||
| NoviceF |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
Если только ты используешь, чем плох
? На дебаге тебе же самому будет полезно сразу видеть где ошибка, вместо того, чтобы лишний раз расставлять printf() или лезть в отладчик, а в релизе этой проверки просто не будет, так что на быстродействии функции в конечном итоге эта проверка вообще не отразится и никакой двойной работы небудет. Добавлено через 6 минут и 37 секунд
Не обязательно.. В большинстве случаев вполне можно зарезервировать какое-нибудь значение для ошибки (например возвращать объект, сконструированные дефолтным конструктром, вместо инициализированного (наверно не очень эффективно, но как вариант), а если из-за данной ошибки программа не должна выполняться дальше или нужно её обрабатывать специальным образом - можно кинуть исключение. У меня вообще нет никакой принципиальной позиции в этом вопросе, но небольшой практический опыт говорит, что лучше проверять.. |
||||||
|
|||||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: нет Всего: 2 |
Я пишу программы в Builder XE. Там при запуске программы в отладочном режиме, если происходит сбой, место в программе где произошел сбой выявляется автоматически. Так что если бы вдруг затупила эта функция, то отладчик бы на нее и указал. То есть это как сигнал для меня, что при передаче аргумента в эту функцию я не все внештатные ситуации обработал. |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
независимо от того, в чем ты пишешь, ошибка произойдет не в месте assert, а когда все протухнет. это может оказаться совсем другая функция. в каких-то случаях приложение не обрушится, просто будет работать криво. и ты будешь бегать с бубном в отладчике
|
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |