2010-05-20 3 views
4

Я создал класс, который моделирует временные интервалы в ежедневном графике с переменной градацией, где, например, первый временной интервал составляет 30 минут, но второй временной интервал может быть 40 минут и первый доступный слот начинается с (значение, сравнимое с) 1.C++: определение максимального/минимального пределов для класса

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

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

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

ответ

1

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

2

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

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

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

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

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

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

+0

Спасибо за ваш ответ, Ной. И да, я думаю, что иногда я слишком многословный, но, похоже, у вас не было проблем с этим, и я отправился туда, куда хотел. Да, я хочу «быть напористым о домене моего класса». У меня нет особых проблем с использованием утверждений или try/catch, чтобы убедиться, что я не испортил код, я просто хочу две вещи: иметь возможность предоставлять такую ​​же (или подобную) информацию моим клиентам, чтобы они также могут принимать соответствующие решения, и эта информация может быть предоставлена ​​естественным образом. Спасибо за подсказку об обеспечении общего интерфейса проверки. – luismachuca

2

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

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

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}; 
+0

Самый простой подход - почти всегда лучший. – Crashworks

+0

... еще лучше, используйте перечисления: 'enum {MIN_SLOT = 1, MAX_SLOT = 999};', и вы можете использовать их время компиляции. –

+0

перечисления - тоже хорошая идея. Я отредактирую свой ответ, чтобы это отразить. –

Смежные вопросы