Reputation: 23
Say I have class galaxy
. A sensible variable to include in this class would be double mass
. Practically, this is an example of a variable that would have inherent restrictions, especially if considering the galaxies we know of today.
What I want to know is: how would you encode this restriction in the class? I would want an error when trying to create galaxy Andromeda(unfeasible mass)
for example.
You can obviously do error checks on inputs if you're taking in data, but is there a way to make this inherent in the class?
Upvotes: 1
Views: 1389
Reputation: 1
You can simplify input checking, with a simple wrapper class, to make the check easier
template<typename T, T MinRange_, T MaxRange_>
struct RangeRestrictedValue {
T value;
RangeRestrictedValue(const char* paramName_ = nullptr)
: value(doRangeCheck(T())), paramName(paramName_) {}
RangeRestrictedValue(const T& value_, const char* paramName_ = nullptr)
: value(doRangeCheck(value_)), paramName(paramName_) {}
RangeRestrictedValue& operator=(const T& value_) {
value = doRangeCheck(value_);
return *this;
}
static T& doRangeCheck(const T& value) {
std::ostringstream message;
message << (paramName ? paramName : "value") << " is out of range.";
if(value < MinRange_ || value > MaxRange_) {
throw std::out_of_range(message.str().c_str());
}
}
const char* paramName;
};
And use that like
class Galaxy {
private:
typedef RangeRestrictedValue<double,MIN_GALAXY_MASS,MAX_GALAXY_MASS> GalaxyMass;
GalaxyMass mass;
public:
Galaxy(double mass_) : mass(mass_,"mass") {}
double mass() const { return mass.value; }
void mass(double mass_) { mass = mass_; }
void doSomething() {
// access mass.value as you need to
}
};
Upvotes: 1