본문 바로가기

책 스터디

(10)
[Exceptional C++ Style] 23. new와 예외, 2부 : 메모리 관리의 실질적인 문제들 이번 챕터에서는 new 할당 시도시 예외를 어떻게 보고하는 것이 바람직한가? 라는 질문과 new 할당 실패를 점검할 때에는 정말로 무엇을 점검해야 하는지, 그리고 과연 점검할 수 있느냐에 대한 이야기를 하고 있다. 책의 내용에 사실 새로울 만한 것이 없고, 평소 생각과 크게 다르지 않기에 요약만 정리하겠다. 메모리가 충분하지 않을 때 C++ 표준 new 함수들이 오류를 보고하는 주 된 형태 두 가지는? 1. std::bad_alloc을 던지는 방법 2. 예외를 던지지 않고, NULL을 리턴하는 방법 핵심 요약 1. nothrow new를 가급적 피할 것. : new 할당이 실패할 정도면 사실 시스템이 제대로 동작하고 있다고 보기 힘들다. : 최대한 gracefully-closing을 할 수 있도록 스택 ..
[Exceptional C++ Style] 22. new와 예외, 1부 : 여러 종류의 new 이번 챕터에서는 new 함수의 여러 종류에 대해 알아보고, 커스텀 할당자(operator new를 재정의하는)를 제작할 때 주의해야 할 점에 대해 기술하고 있다. 아울러, new 함수 중 예외를 던지지 않는 new 함수에 대한 경고도 함께 이야기하고 있다. 신참 질문 C++ 표준에 있는 new 함수는 어떠한 종류들이 있는가? C++ 표준은 다음과 같은 new 함수들을 제공하며, 추가적으로 그것들을 얼마든지 overload 할 수 있도록 허용한다. // 표준이 제공하는 operator new의 overloaded functions // 이외 배열에 해당하는 operator new [] 도 있지만, 규칙은 동일하므로 예시에선 제외... // 1. 보통의 평범한 new : 용법 new T void* ::ope..
[Exceptional C++ Style] 21. 컨테이너 메모리 사용 2부 : 얼마나 큰가? 이번 챕터에서는 우선 메모리 할당시 실제 할당되는 크기에 대해 간략하게 이야기한 뒤, vector, list, set(map)에 요소를 추가할 때 발생하는 비용과 바이트 정렬(alignment)을 곁들어 실제로 사용되는 메모리 크기에 대해 이야기한다. 신참 질문 new나 malloc으로 메모리 n 바이트 할당 요청시 실제로 할당되는 크기는 정확하게 크기 n과 일치하는가? 그렇지 않다면, 그 이유는 무엇인가? new나 malloc으로 n 바이트의 메모리를 요청했을 때, 실제로는 '적어도' n 바이트의 메모리를 할당하게 된다. 즉, n 바이트 이상의 메모리를 사용하게 될 수도 있는 것이다. 이는 메모리 관리자가 요청에 약간의 추가 비용을 부담하기 때문이다. 일반적으로 그러한 추가 부담에는 1) 관리를 위한 ..
[Exceptional C++ Style] 19. 파생된 클래스들에 대한 규칙 강제 이번 챕터에서는 C++ 클래스에 대해 컴파일러가 암묵적으로 생성하는 함수들에 대해 이야기하면서, 이러한 바탕 하에서 파생 클레스들에 대해 어떠한 규칙들을 강제할 수 있는지 설명하고 있다. 역시나 기본적인 내용이지만, 중요한 기본이기에 짚고 넘어가도록 하자. 신참 질문 하나의 클래스에 대해 암묵적으로 선언, 정의되는 함수들은 무엇이며, 선언과 정의되는 때는 언제인가? 그리고 그런 선언과 정의들은 어떠한 의미론을 가지는가? C++ 컴파일러는 클래스를 컴파일할 때 다음 네 가지 함수들이 존재하는지 체크해 존재하지 않으면, 컴파일러가 알아서 암묵적으로 이들을 선언한다. 이러한 암묵적은 생성은 1) 편의를 위한 것이자, 2) C와의 하위 호환성을 위한 것이다. C++에서 C 스타일의 struct는 오직 publi..
[Exceptional C++ Style] 18. 클래스 가상성 가상성이라...책 제목에 대한 번역 참 마음에 안 든다... 이 챕터에서는 가상 함수에 대한 공개(public, protected, private) 수준과 부모 클래스의 소멸자를 가상 함수로 해야 하는가에 대해 이야기 하고 잇으며, 그 이야기들로부터 좋은 설계를 위한 지침을 안내하고 있다. 상속 관계와 가상성은 늘 도마 위에 올라 지겹게 보는 내용이지만, 다시 한 번 리마인드하는 것도 나쁘지 않을 듯 하다. 1. 가상 함수들을 언제 public/protected/private으로 해야 할까? 가상 함수의 공개 여부에 대해 표어를 하나 만들어보면 다음과 같을 것이다. public은 '드물게', protected는 '가끔', private는 '기본적으로' 사실 위 표어는 비단 가상 함수뿐 아니라 클래스의 다..
[Exceptional C++ Style] 16. private는 얼마나 비공개적인가? 이번 챕터는 private 키워드의 비공개성에 대해 접근성과 가시성이라는 두 가지 측면에서 설명하고 있다. 그리고, private 멤버에 대해서 클래스 외부의 non-friend 코드가 private 이름에 접근할 수 있는 방법들에 대해서 설명하고 있지만, 이 부분은 사실 이렇게하면 할 수 있다는 이야기이지 바람직한 부분은 아니기에 굳이 정리하지 않겠다. 물론 아주 기초적인 내용이지만, 한 번쯤 정독과 고찰을 해 볼 필요는 있어 보인다. 특히, 컴파일러가 함수 호출을 결정하는 순서는 가급적 확실하게 이해를 하고 있어야 한다. 고수 질문 Twice 함수들이 링크 과정에 포함되는 다른 어떤 번역 단위에 정의되어 있다고 할 때(cpp에 되어 있겟지), 다음의 프로그램이 제대로 컴파일, 실행될까? 아니라면 왜 ..
[Exceptional C++ Style] 14. 클래스 객체 생성(소멸) 순서의 중요성 이 챕터에서는 클래스가 상속 관계를 가질 때, 특히 생성자와 소멸자의 처리 순서에 대해 다루고 있다. 기본 클래스로부터 상속받은 파생 클래스가 생성될 때 어떠한 순서로 생성 처리가 되며, 이러한 순서에 대해 정확한 이해없이 코드를 만들면 어떠한 문제가 생기는 지 알아본다. 신참 질문 다음 코드에서 무엇이, 그리고 왜 잘못 되었는가? #include using namespace std; class Base { public: explicit Base(const string& a) { //... } string f() { return "Hello World"; } }; class Derived : public Base { public: Derived() : Base(s = f()) {} private: str..
[Exceptional C++ Style] 8. 템플릿 친구 만들기 (friend function template) 책에서는 friend 함수 템플릿 특수화를 사용하는 케이스에 대해 범위 지정 연산자 (::)를 사용할 수 있는 경우에 대해, 주로 예시를 들면서 범위 지정 연산자가 있을 때 사용할 수 있는 두 가지 방법에 대해 논의한다. 하지만 실제 범위 지정 연산자를 쓸 수 없는 경우(클래스 정적 멤버가 아니거나 네임스페이스 속에 있지 않거나)도 많기에 이번 챕터 정리는 책과 조금 다르게 풀어갈 생각이며, (범위 지정 연산자를 사용하는 경우를 예외적으로 소개하겠다) 책에서 얘기하고 있는 friend 함수의 조건도 바뀐 C++ 0X 기준으로 설명하겠다. 주어진 객체에 대해 로그를 남긴 후 삭제하는 다음 함수 템플릿이 있다고 하자. template void LoggedDelete(T* t) { // 로그를 남겨라 dele..