2017-02-23 85 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'的類來檢查* its *構造函數中的範圍。 – 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',否則將不能編譯。否則這是一個很好的解決方案。只有三點建議:(1)將'value'設爲private,添加一個getter函數和一個執行與doRange相同檢查的setter。如果沒有,你可以在施工結束後打破不變。 (2)添加一個'static_assert'來確保'MinRange <= MaxRange_'。 (3)將'message'的範圍限制在'if'塊。 –

+0

@Christian考慮到我已經改變了我的答案。 –

+0

字符串文字不能是模板值參數,因爲它們具有內部鏈接。 –