2017-11-18 19 views
2

초기화 목록을 호출하기 전에 클래스 생성자에서 매개 변수에 대해 무언가를 주장 할 수 있습니까?클래스 초기화 목록 앞에 어설 션을 어떻게 배치 할 수 있습니까?

class Foo 
{ 
    int m_lower; 
    int m_upper; 
    unsigned int m_delta; 

    public: 
    Foo(int t_lower, int t_upper) : 
     assert(t_lower < t_upper), // Assert here, before initialisation of fields. 
     m_lower(t_lower), 
     m_upper(t_upper), 
     m_delta(t_upper - t_lower) 
    { 
     // Assert could be made here, but m_delta would have underflowed if t_upper < t_lower. 
    } 
} 

초기화 목록 전에 어설의 장점은 각 필드의 초기화에 대한 요구 사항을 즉시 할 수와 같은 요구 사항이 각 초기화 잠재적으로 여러 번 점검 할 필요가 없습니다 것이라고 할 것이다. init_delta 초기화 메소드에서 m_delta의 초기화를 만들 수 있지만, 여러 값이 동일한 요구 사항이 t_upper > t_lower 인 경우 각각의 값에 어설 션을 배치해야합니다 (이전 어설 션이 제거 된 경우). 생성 함수 자체에 배치되면 하나 이상의 필드의 초기화가 이미 실패했을 수 있습니다 (언더 플로우보다 더 극적인 것).

초기화 목록의 맨 위에 놓는 경우 계약서는 검사시 사용자에게 명확하며이 경우 언더 플로와 같은 오류가 발생하기 전에 오류를 표시합니다.

위의 경우는 문제의 단순한 예일뿐입니다. 위의 특정 문제 (abs() 등)를 해결하는 더 좋은 방법이 있다는 것을 알고 있습니다.

도움과 조언에 감사드립니다.

+0

일반적인 어설 션 (예 : )은 앱을 '중단'합니다. 따라서, 나는 당신이 주장을 한 번하는 곳에는 이점이 없다고 생각합니다. IMHO, 대부분의 독자는 ctor의 유용한 주장을 기대합니다. 일부는 ctor를 호출하기 전에 어설 션을 선호 할 수도 있습니다. –

답변

3

넌 콤마 연산자 사용할 수 콤마 연산자

public: 
    Foo(int t_lower, int t_upper) : 
     m_lower(assert(t_lower < t_upper), t_lower), 
     m_upper(t_upper), 
     m_delta(t_upper - t_lower) 
    { 
     ... 
    } 

피연산자 평가를 왼쪽에서 오른쪽, 오른쪽 값이 결과로서 사용된다.

초기화 순서는 초기화 목록의 순서가 아니라 클래스에서 멤버 변수가 선언 된 순서를 기반으로합니다. 따라서 assert() 호출을 첫 번째 멤버 변수의 초기화에 넣어야합니다.

+0

쉼표 힌트를 보내 주셔서 감사합니다.이 기능을 알지 못했습니다! 그러나이 경우에도 동일한 어설 션이 필요한 각 필드에 대해 어설 션이 필요합니다. – Arc

+0

아니요. 첫 번째 멤버 변수에 넣으면됩니다. – Barmar

+0

'assert'가 표현식으로 사용 가능하다는 보장이 있습니까? – Angew