2017-02-23 4 views
1

class galaxyと言います。このクラスに含める賢明な変数はdouble massです。実際には、これは、特に私たちが今日知っている銀河を考えれば、固有の制限を持つ変数の例です。クラス(C++)で宣言された変数の範囲を定義しますか?

私が知りたいことは、このクラスをどのようにエンコードするかです。たとえば、galaxy Andromeda(unfeasible mass)を作成しようとするとエラーが発生します。

データを取り込んでいるときは、明らかに入力のエラーチェックを行うことはできますが、クラスにこれを固有にする方法はありますか?

+0

のように、私は100%わからないんだけど、あり得ることを使用のチェックを容易にするために、単純なラッパークラスを使用して、入力チェックを簡素化することができます[ユーザー定義リテラル](http://en.cppreference.com/w/cpp/language/user_literal)は、あなたのケースで役立つ可能性があります。だから、基本的には、コンパイル時に適用できる値の監視範囲を特定したいのですか?より簡潔なサンプルを提供する必要があります。コードをどのように見せるか –

+0

標準のC++で有効な範囲を宣言する方法はありません。最も一般的な方法は、入力をテストし、範囲外の場合はエラーを返すことです。このケースではコンストラクタでは使用しないことをお勧めしますが、カプセル化を使用してこれを行うアクセサとミューテータを作成することがあります https://en.wikipedia.org/wiki/Encapsulation_(computer_programming) – Ben

+0

クラスのコンストラクタで範囲を調べるか、またはそのコンストラクタの範囲をチェックする 'GalaxyMass'というクラスを作成します。 – rlbond

答えて

1

あなたは

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

そして

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

'doRangeCheck'は' value'を返さなければなりません。さもなければ、これはコンパイルされません。そうでなければ良い解決策です。ちょうど3つの提案:(1) 'value'をプライベートにし、ゲッター関数と' doRange'と同じチェックを行うセッターを追加します。もしそうでなければ、建設後に不変条件を破ることができます。 (2) 'MinRange <= MaxRange_'を確認する' static_assert'を追加します。 (3) 'message'のスコープを' if'ブロックに制限します。 –

+0

@Christian私はそれを考慮して私の答えを変えました。 –

+0

文字列リテラルは、内部のリンケージを持つため、テンプレートの値パラメータにすることはできません。 –

関連する問題