2014-07-08 4 views
1

프로젝트에서 저는 기본적으로 정수 타입을 감싸는 클래스를 만들었습니다. 나는 몇 가지 이유로 이것을 선택한다. 먼저 내 가치에 대해 구체적인 것을 알려주는 메소드를 추가하고 싶습니다. 예를 들어 나는이 그냥 예입니다 (is_odd()라는 방법을 가질 수 둘째, 나는 값이 유효한 범위 내에서 항상 확인 할object와 stil 같은 정수에 유효한 값만 반복하는 방법은 무엇입니까?

을 그래서 내 클래스는 다음과 같이 할 수있다 :..

class C { 
public: 
    // Constructor and some other stuff here including 
    // post and pre increment operators 

    inline void CheckInvariant() const 
    { assert(0 <= value_ && value_ <= 8);}; 
private: 
    std::uint8_t value_; 
}; 

는 지금은이 클래스의 가능한 모든 값을 반복 할 이처럼 :.

for (C c(0); c <= c::max_value; ++c) 
{ 
    // Do something 
} 

심지어 같은 :

// Note here that C::min_value <= c is always true 
// because the value wrap-around. 
for (C c = C::max_value; C::min_value <= c; --c) 
{ 
    // Do something 
} 

문제는 c가 무효가되어서 c::max_value 이후로 증가하고 연산자에서 CheckInvariant()를 호출하면 ++가 실패합니다.

처음에는 모든 유효 값을 배열에 반복 할 수 있지만이를 사용하는 코드는 실제로 성능에 치명적이며 정수를 직접 사용하는 것보다 빠를 필요가 있습니다. 바인드되는 것은 디버그 모드 (어설트)에서 체크됩니다.

이제 나는 "냄새"와 디자인에 결함이 있음을 이해합니다. 유효하지 않은 값을 방지하고 모든 값을 효율적으로 반복 할 수있는 알려진 패턴이 있습니까?

도움 주셔서 감사합니다.

+0

증분/감소 대신 역 참조 연산자에서 불변량을 확인하십시오. –

+0

클래스의 반복자를 작성하고 for 루프를 사용할 수 있습니다. – yngccc

+0

@yngum 나는 이것에 대해 힘들지만, 정수를 증가시키는 것보다 덜 효율적이라고 생각하는 것이 맞습니까? 이 코드는 실제 성능에 중요한 루프에서 사용됩니다. –

답변

0

이 솔루션은 을 통해 반복 할 때 가능한 모든 값이 정수 유형입니다.

C c(0); 
do 
{ 
    // Do something 
} 
while(++c != c(0)); 

참고이 할-동안 솔루션을 허용 값의 범위는하지 빈 세트 것으로 가정합니다.

1

실제로 여기에 두 개의 불변량이있는 것처럼 보입니다.

첫 번째는 값에 액세스하면 지정된 범위 내에 있어야한다는 것입니다. 두 번째는 증가 후 지정된 범위를 초과하지 않아야한다는 것입니다. 나는 당신의 최선의 접근법이 그 두 가지 조건에 대해 두 가지 불변 수표라고 믿습니다.

마지막으로 is_odd과 같은 멤버 함수는 이러한 기능을 구현하는 올바른 방법이 아닙니다. 대신 클래스와 밀접하게 결합되지 않은 범용 코드를 제공하기 위해 자유 함수 알고리즘으로 구현해야합니다.

+0

답변 해 주셔서 감사합니다. 나는 두 개의 불변량을 가지고 있고 범위를 벗어나는 값을 허용해야한다는 사실에 대해 당신이 맞다고 생각합니다. is_odd는 실제 클래스 기능을 추상화하는 데 사용되는 예제입니다. 귀하의 답변에 감사드립니다. 나는 지금 그것을 upvote하고 아마도 나중에 받아 들일 것이다. –

관련 문제