C ++: определение максимальных / минимальных ограничений для класса - PullRequest
4 голосов
/ 20 мая 2010

Я создал класс, который моделирует временные интервалы в ежедневном расписании с переменной гранулярностью, где, например, первый временной интервал составляет 30 минут, но второй временной интервал может составлять 40 минут, а первый доступный временной интервал начинается с ( значение, сопоставимое с) 1.

Что я хочу сделать сейчас, так это определить как-то максимальные и минимальные допустимые значения, которые принимает этот класс, и у меня есть два практических вопроса для этого:

1.- Имеет ли смысл определять абсолютный минимум и максимум таким образом для пользовательского класса? Или лучше, достаточно ли того, чтобы значение всегда сравнивалось как меньшее, чем любое другое возможное значение типа, учитывая определенные в классе операторы отношений, которые должны быть определены как min? (и аналогично для макс)

2.- Если предположить, что на предыдущий вопрос есть ответ, смоделированный после "да" (или "да, но ..."), как определить такой максимум / мин? Я знаю, что есть std::numeric_limits<>, но из того, что я прочитал, оно предназначено для «числовых типов». Должен ли я интерпретировать это как означающее «представленный как число», или я могу сделать более широкое предположение, такое как «представленный числами» или «имеющий соответствие целым числам»? В конце концов, имело бы смысл определить минимум и максимум для класса даты и, возможно, для класса словаря, но numeric_limits может не предназначаться для этих целей (у меня нет особого опыта работы с ним). Плюс, у numeric_limits есть много дополнительных участников и информации, с которой я не знаю, что сделать. Если я не использую numeric_limits, какой другой хорошо известный / широко используемый механизм предлагает C ++ для указания доступного диапазона значений для класса?

Ответы [ 3 ]

2 голосов
/ 20 мая 2010

Трудно разобраться в вашем вопросе. Я думаю, что вы спрашиваете, имеет ли смысл быть уверенным в отношении области класса (те данные, которые могут быть переданы ему и имеют смысл), и если да, то как быть уверенным.

Первый имеет очень четкий ответ: да, абсолютно. Вы хотите, чтобы ваш класс был «... простым в использовании и трудным в использовании». Это включает в себя проверку того, что клиентам класса сообщают, что они делают что-то не так.

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

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

Для вашего класса вы можете рассмотреть несколько способов обеспечить мин / макс. Одним из них является предоставление функций min / max в интерфейсе класса. Другой может заключаться в использовании внешних функций, и да, numeric_limits может быть просто вещь, поскольку диапазон иногда является типом числового количества. Вы могли бы даже предоставить более общий интерфейс, который имеет функцию validate_input () в вашем классе, чтобы вы могли сделать любое сравнение, которое может быть уместным.

Во второй части вашего вопроса есть много правильных ответов в зависимости от множества переменных, включая личный вкус.

2 голосов
/ 20 мая 2010

Как разработчик кода вашего расписания / слота, вы сами решаете, сколько гибкости / практичности вы хотите.

Два простых подхода - определить ваши собственные значения в этом классе

const long MIN_SLOT = 1;
const long MAX_SLOT = 999; // for example

Или определите другой класс, содержащий определения

class SchedLimits{

public:
const static long MIN_SLOT = 1;
const static long MAX_SLOT = 999;
}

Простейшим из всех будет перечисление. (моя благодарность комментатору, который напомнил мне о тех)

enum {MIN_SLOT = 1, MAX_SLOT = 999};
1 голос
/ 20 мая 2010

Просто создайте некоторые постоянные статические элементы, которые отражают минимумы и максимумы.

...