Chapter 2 - 2. The Basics, Error Handling

2.4.3 Error Handling ~ 2.5 postscript

- 본 문은 노트 정리 차원에서 기술한 내용입니다.


에러 핸들링을 위한 편의 시설 - 시스템 그 자체. 빌트인 타입과 if 문 등의 statement 만이 아닌 어플리케이션에 적합한 타입 ( string / map .. ) 이용하고 알고리즘들을 이용할수있다. 이런 고수준 구조가 존재 할 수록 버그를 만들 여지가 줄고 에러를 더 잡기 쉬움.

가장 중요한 것은 추상화.


2.4.3.1 Exceptions

vector 구현자에게 있어 out of range 에러를 사용자에게 알려주고 싶다.

예를 들면 다음과 같이 연산자 오버로딩을 통해 에러를 던질 수 있다.


double& Vector::operator[](int i)

{

if (i<0 || size()<=i) throw out_of_rang e{"Vector::operator[]"};

return elem[i];

}


throw 는 out-of-range 타입의 예외를 연산자 호출부로 전달한다.

그러기 위해 콜스택 풀기가 필요. 


try - 블럭으로 예외가 발생할 것 같은 곳에 두고 catch 로 발생한 예외를 잡아낸다.

이 메커니즘은 에러 핸들링을 간단/시스템적으로/가독성있게 만들어준다.



2.4.3.2 Invariants

vector 의 멤버가 어떤 타당한 값을 가지고 있지 않으면 아무 의미도없다. 주석을 통해 elem 은 double 형의 sz 개의 배열을 가지고 있어야 하지만 이를 강제하는 것은 없다. 이렇게 어떤 클래스가 유효함을 보장하기 위해 사실이어야 하는 진술이 class invariant 라고 불림.

생성자를 통해 초기화 되어 소멸자가 호출되기 전까지 지켜져야함


invariant 보장을 위해 다음과 같이 정의 

Vector::Vector(int s)

{

if (s<0) throw length_error{};

elem = new double[s];

sz = s;

}

standard-library 의 length-error 사용.

보통 에러를 '핸들링' 한다는 것은 최소한의 로컬 클린업과 rethrowing exception 을 의미.


클래스의 invariant , 함수의 preconditions 는 비슷하다. 

invariant 는

- 우리가 뭘 원하는지 이해하는데 도움을 준다

- 특정한 것에 초점을 맞추게 한다. ( 디버깅 / 테스트 후에 우리 코드를 올바르게 만들 수 있는 더 많은 기회)


2.4.3.3  static assertions

컴파일 타임 체크. - 다라서 constexpr 로 표현되는 predicate 여야한다.

static_assert(<predicate>, <message>);