nds_r
nds_r

Reputation: 23

Defining ranges for variables declared in a class (C++)?

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

Answers (1)

πάντα ῥεῖ
πάντα ῥεῖ

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

Related Questions