views:

77

answers:

3

Basically what the title says... I have created a class that models time slots in a variable-granularity daily schedule (where for example the first time slot is 30 minutes, but the second time slot can be 40 minutes); the first available slot starts at (a value comparable to) 1.

What I want to do now is to define somehow the maximum and minimum allowable values that this class takes and I have two practical questions in order to do so:

1.- does it make sense to define absolute minimum and maximum in such a way for a custom class? Or better, does it suffice that a value always compares as lower-than any other possible value of the type, given the class's defined relational operators, to be defined the min? (and analogusly for the max)

2.- assuming the previous question has an answer modeled after "yes" (or "yes but ..."), how do I define such max/min? I know that there is std::numeric_limits<> but from what I read it is intended for "numeric types". Do I interpret that as meaning "represented as a number" or can I make a broader assumption like "represented with numbers" or "having a correspondence to integers"? After all, it would make sense to define the minimum and maximum for a date class, and maybe for a dictionary class, but numeric_limits may not be intended for those uses (I don't have much experience with it). Plus, numeric_limits has a lot of extra members and information that I don't know what to make with. If I don't use numeric_limits, what other well-known / widely-used mechanism does C++ offer to indicate the available range of values for a class?

+1  A: 

Just create some const static members that reflect the minimums and maximums.

DeadMG
+1  A: 

Having trouble making sense of your question. I think what you're asking is whether it makes sense to be assertive about the class's domain (that data which can be fed to it and make sense), and if so how to be assertive.

The first has a very clear answer: yes, absolutely. You want your class to be, "...easy to use correctly and difficult to use incorrectly." This includes making sure the clients of the class are being told when they do something wrong.

The second has a less clear answer. Much of the time you'll simply want to use the assert() function to assert a function or class's domain. Other times you'll want to throw an exception. Sometimes you want to do both. When performance can be an issue sometimes you want to provide an interface that does neither. Usually you want to provide an interface that can at least be checked against so that the clients can tell what is valid/invalid input before attempting to feed it to your class or function.

The reason you might want to both assert and throw is because throwing an exception destroys stack information and can make debugging difficult, but assert only happens during build and doesn't actually do anything to protect you from running calculations or doing things that can cause crashes or invalidate data. Thus asserting and then throwing is often the best answer so that you can debug when you run into it while testing but still protect the user when those bugs make it to the shelf.

For your class you might consider a couple ways to provide min/max. One is to provide min/max functions in the class's interface. Another might be to use external functionality and yes, numeric_limits might just be the thing since a range is sometimes a type of numeric quantity. You could even provide a more generic interface that has a validate_input() function in your class so that you can do any comparison that might be appropriate.

The second part of your question has a lot of valid answers depending on a lot of variables including personal taste.

Noah Roberts
Thanks for your answer, Noah. And yes, I think I am too verbose sometimes, but you seemed to have no trouble with it and went exactly where I wanted to go.Yes, I want to "be assertive about my class's domain". I don't have much trouble with using asserts or try/catch to make sure I don't screw up with the code, I just want two things: to be able to provide the same (or similar) information to my clients so that they too can take decisions accordingly, and that information can be provided in a natural manner.Thanks for the hint on providing a generic validation interface.
luismachuca
+2  A: 

As the designer of your schedule/slot code, it's up to you as to how much flexibility/practicality you want.

Two simple approaches would be to either define your own values in that class

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

Or define another class that holds the definitions

class SchedLimits{

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

Simplest of all would be enums. (my thanks to the commenter that reminded me of those)

enum {MIN_SLOT = 1, MAX_SLOT = 999};
Kelly French
The simplest approach is almost always the best.
Crashworks
...even better, use enums: `enum {MIN_SLOT = 1, MAX_SLOT = 999};`, and you can use them compile time.
Viktor Sehr
enums are a good idea too. I'll edit my answer to reflect that.
Kelly French
Thanks for the comment. I would have gone the class-with-constraints idea, but I was looking for something more "natural" in the "ints do it that way too" sense. However as Crashworks mentions, the simplest approach may be the best, and I might just be headaching for nothing.Thanks, again.
luismachuca
You can use static const integral fields at compile time as well.
Dennis Zickefoose