본문 바로가기

책 정리/Exceptional C++

(50)
Exceptional C++ 차례 반드시 읽어 볼 만한 책인것을 확신하며, 꼭 읽어보길 바란다. 번역 또한 깔끔하게 되어서, 읽는데는 문제가 없다. 이해하는것에 있어서는 기본 지식을 무척이나 많이 필요하기 때문에, .. 어리둥절하게 만드는 경우가 많으니, 비야네 책과 같이 보면 큰 도움이 될 듯 싶다. 차례 1. 일반 프로그래밍과 C++ 표준 라이브러리 항목 1 : 반복자(Iterator) 항목 2 : 대·소문자 구분 없는 문자열 - 파트 1 항목 3 : 대·소문자 구분 없는 문자열 - 파트 2 항목 4 : 최대 재사용 가능한 일반 컨테이너 - 파트 1 항목 5 : 최대 재사용 가능한 일반 컨테이너 - 파트 2 항목 6 : 임시 개체들 항목 7 : 표준 라이브러리의 사용(혹은, 다시 보는 임시 개체) 2. 예외 안전 문제와 기술들 여담 ..
항목 19 : 코드 복잡성 - 파트 2 (난이도 7) 항목 18에서 얼마나 많은 예외가 발생할 수 있는지 알아 보았다면, 이번 항목에서는 어떻게 하면 그런 예외들을 잡을 수 있을까? 에 대한 고민을 하게 해 준다. 예제 코드 string EvaluateSalaryAndReturnName( Employee e ) { if( e.Title() == "CEO" || e.Salary() > 100000 ) { cout
항목 17 : 예외에 안전한 코드를 작성하기 - 파트 10 (난이도 9/½) 지긋지긋하고 힘빠지는 예외안전성 생각하기의 막바지 항목이다. 이번 항목은 아주 중요한 질문을 던진다고 한다. C++ 표준 라이브러리가 예외에 안전한가? .... 결론부터 말하자면, 예외에 안전하다. 이것은 C++ 표준 사항에서 규정된 사항인데, 아래 규정을 보도록 하자. 표준 컨테이너에서 반환되는 모든 반복자는 예외에 안전하고 예외를 던지지도 않으며 복사 될 수 있다. 모든 표준 컨테이너는 모든 연산에 대한 기본 보증을 구현해야 하며, 항상 파괴와 예외가 있어도 견고한 상태를 유지 할 수 있어야 한다. 모든 컨테이너는 또한 반드시 모든 연산에 대해서 강한 보증을 구현해야 한다. 이것의 의미는 수행-또는-되물림(commit-or-rollback) 의 논리를 갖어야 한다는 의미이다. 성공하거나, 그 어떤 영..
항목 16 : 예외에 안전한 코드를 작성하기 - 파트 9 (난이도 8) 이전 항목(15)에서 T의 요구사항 중 한가지인 소멸자에서 예외를 발생시키지 않아야 한다고 이야기 했던것을 기억 한다면, 왜 소멸자에서 예외를 발생 시키면 안되는지에 대해서 풀어 보도록 하자. 한가지 전제를 하여 T *p = new T[10]; delete[] p; 위의 코드드 중 소멸자에서 예외가 발생 된다면, 어떤 문제점이 발생 할 수 있을까? 첫번째, 만약 생성은 모두 성공하고 delete[] 처리 중 5번째꺼에서 파괴가 된다면 어떻게 될까? 5번째부터 10번째꺼는 파괴 불가능한 상태 되는 문제가 남는다. 이것은 p[0] 가 파괴 되었기 때문에 다시 delete[] p; 를 할 수 없기 때문이다. 두번째, 만약 생성 도중 예외가 발생하여, T의 소멸자를 호출해야 할 때, 예외가 발생 한다면, 어떻게..
항목 15 : 예외에 안전한 코드를 작성하기 - 파트 8 (난이도 9) 이번 항목은 저번 13항목, 14항목에서 만들어보았던 private 기반 상속과 HAS-A 기반 관계에 대해 비교해 보는 항목이다. StackImple을 private 기반 클래스나 멤버 개체로 사용하는 것 중에 어느 기법이 더 좋은가? Stack의 두 버전은 얼마나 재사용 가능한가? 내재된 데이터형인 T의 요구사항은 무엇인가? Stack은 함수에 대한 예외 규격을 제공해야 하나? 생각해 보자. 1. private 상속이 좋은가? HAS-A 관계가 좋은가? 왜 이런 비교를 하는고 하면, 두 상속 모두 "구현 상속" 이라는 명제가 깔리기 때문이다. 클래스 기반 상속은 HAS-A 기반 관계 보다 더 관계를 맺는다.. 마치 머리에 붙은 껌 같이 강력하다. 그렇기 때문에 대부분의 사람들은 HAS-A 관계으로도 ..
항목 14 : 예외에 안전한 코드를 작성하기 - 파트 7 (난이도 5) 항목 13 에선 StackImpl 이 protected 를 나타내어 private 상속을 통하여 Stack 을 구현했다면, 이번에는 /?????/ 이 부분이 public 인터페이스일 경우, HAS-A 관계를 이용하여 Stack 을 구현해 보자. 코드 template class StackImpl { /* ? ? ? ? ? */ StackImpl( size_t size = 0 ); ~StackImpl(); void swap( StackImpl& other ) throw(); T* v_; size_t vsize_; size_t vused_; private: // private and undefined: 복사가 허용되지 않음 StackImpl( const StackImpl& ); StackImpl& operat..
항목 13 : 예외에 안전한 코드를 작성하기 - 파트 6 예제코드 template class StackImpl { /* ? ? ? ? ? */ StackImpl( size_t size = 0 ); ~StackImpl(); void swap( StackImpl& other ) throw(); T* v_; size_t vsize_; size_t vused_; private: // private and undefined: 복사가 허용되지 않음 StackImpl( const StackImpl& ); StackImpl& operator=( const StackImpl& ); }; template class Stack : private StackImpl { public: Stack( size_t size = 0 ); ~Stack(); Stack( const Stack& ..
항목 24 : 상속의 사용과 남용 (난이도 6) 경험 많은 개발자라도 상속을 남용 하는 경우가 많이 있다. 상속은 머리에 껌이 달라 붙는것 처럼 띄어내기가 참 어려운 구조이기 때문에, 필요할때만 사용 해야 한다. 자.. 예제코드를 봐보자. 코드 /*예제 1 */ template class MyList { public: bool Insert( const T&, size_t index ); T Access( size_t index ) const; size_t Size() const; private: T* buf_; size_t bufsize_; }; /*예제 1(a) */ template class MySet1 : private MyList { public: bool Add( const T& );// Insert() 호출 T Get( size_t inde..