說我有class galaxy
。包含在這個類中的一個明顯的變量是double mass
。實際上,這是一個變量的例子,它會有固有的限制,尤其是考慮到我們今天所知道的星系。定義在類(C++)中聲明的變量的範圍?
我想知道的是:你會如何在課堂上編碼這個限制?例如,在嘗試創建galaxy Andromeda(unfeasible mass)
時,我想要一個錯誤。
如果你正在接收數據,你可以明顯地對輸入進行錯誤檢查,但是有沒有辦法讓這個類固有呢?
說我有class galaxy
。包含在這個類中的一個明顯的變量是double mass
。實際上,這是一個變量的例子,它會有固有的限制,尤其是考慮到我們今天所知道的星系。定義在類(C++)中聲明的變量的範圍?
我想知道的是:你會如何在課堂上編碼這個限制?例如,在嘗試創建galaxy Andromeda(unfeasible mass)
時,我想要一個錯誤。
如果你正在接收數據,你可以明顯地對輸入進行錯誤檢查,但是有沒有辦法讓這個類固有呢?
您可以簡化輸入檢查,用一個簡單的包裝類,使檢查更容易
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
}
};
'doRangeCheck'必須返回'value',否則將不能編譯。否則這是一個很好的解決方案。只有三點建議:(1)將'value'設爲private,添加一個getter函數和一個執行與doRange相同檢查的setter。如果沒有,你可以在施工結束後打破不變。 (2)添加一個'static_assert'來確保'MinRange <= MaxRange_'。 (3)將'message'的範圍限制在'if'塊。 –
@Christian考慮到我已經改變了我的答案。 –
字符串文字不能是模板值參數,因爲它們具有內部鏈接。 –
我不是100%肯定,但可能[用戶定義文字](http://en.cppreference.com/w/cpp/language/user_literal)可以幫助你的情況。那麼基本上你想要指定一個可以在編譯時應用的值的監視範圍?你應該給我們一個更簡潔的例子,你期待代碼的樣子。 –
無法在標準C++中聲明有效範圍。最常見的方法是測試輸入並在超出範圍時返回/拋出錯誤。在這種情況下,我建議不要將它用在構造函數中,而要使用封裝來創建訪問器和增變器,它可以執行此操作。 https://en.wikipedia.org/wiki/Encapsulation_(computer_programming) – Ben
您或者需要檢查範圍,或者創建一個名爲'GalaxyMass'的類來檢查* its *構造函數中的範圍。 – rlbond