2017-02-23 8 views
1

나는 class galaxy이 있다고합니다. 이 클래스에 포함 할 수있는 변수는 double mass입니다. 실제적으로 이것은 특히 오늘날 우리가 알고있는 은하계를 고려할 때 고유 한 제한이있는 변수의 예입니다.클래스 (C++)에서 선언 된 변수의 범위 정의?

내가 알고 싶은 것은 다음과 같습니다.이 제한을 클래스에서 어떻게 인코딩합니까? 예를 들어 galaxy Andromeda(unfeasible mass)을 만들려고 할 때 오류가 발생합니다.

데이터를 가져 오는 중 입력에 대한 오류 검사를 수행 할 수는 있지만 클래스에 고유하게 적용 할 수있는 방법이 있습니까?

+0

같은 것을 사용하는 것이 아니라 할 수있다 [사용자 정의 리터럴] (http://en.cppreference.com/w/cpp/language/user_literal)이 귀하의 사례에 도움이 될 수 있습니다. 그래서 기본적으로 컴파일 타임에 적용 할 수있는 모니터링 된 값 범위를 지정하고 싶습니까? 보다 간결한 샘플을 제공해야하며 코드가 어떻게 생겼는지 기대하십시오. –

+0

표준 C++에서 유효한 범위를 선언 할 방법이 없습니다. 가장 일반적인 방법은 입력을 테스트하고 범위를 벗어나면 오류를 반환하거나 throw하는 것입니다. 이 경우에는 생성자에서 가져 오지 말고 캡슐화를 사용하여 접근 자 및 뮤 테이터를 만드는 것이 좋습니다. 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; 
}; 

을 그리고 난 100 % 확실하지 않다

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'를 private로 만들고, getter 함수와 setter를 추가하여'doRange'와 같은 체크를합니다. 그렇지 않다면, 건설 후에 불변성을 깨뜨릴 수 있습니다. (2)'MinRange <= MaxRange_'를 확인하기 위해'static_assert'를 추가하십시오. (3)'message'의 범위를'if' 블록으로 제한하십시오. –

+0

@Christian 나는 그것을 고려하여 나의 대답을 바꿨다. –

+0

문자열 리터럴은 내부 연결이 있으므로 템플릿 값 매개 변수가 될 수 없습니다. –