C++/Effective C++

55: Boo子有親! 부스트를 늘 여러분 가까이에 부스트는 C++ 개발자들의 단체이자 무료 다운로드가 가능한 C++ 라이브러리 집합을 동시에 일컫는 고유명사이다. 물론 C++만 다루는 개발자 단체 및 웹사이트는 부스트 말고도 정말 많다. 하지만 부스트는 다른 곳과는 다른 차별점이 있다. 첫째, 부수트는 C++ 표준화 위원회와 밀접하고 영향력 있는 밀월관계를 유지하고 있는 곳으로 유일하다. 둘째, 라이브러리 승인 과정이다. 이곳의 승인 과정은 공개 동료 심사(public peer review)에 기반을 두고 있다. 부수트의 라이브러리 군단은 크게 십수 개의 범주로 나뉘어 있다. 문자열 및 텍스트 처리 타입 안정성을 갖춘 printf 비슷한 서식화 기능, 정규 표현식 및 토큰화와 구문분석 기능 컨테이너 ST..
54: TR1을 포함한 표준 라이브러리 구성요소와 편안한 친구가 되자 C++98에 명시되어 있는 표준 C++ 라이브러리의 주요 구성요소를 한 번 되짚어 보자. 표준 템플릿 라이브러리(Standard Template Library, STL) 컨테이너(vector, string, map 등), 반복자, 알고리즘(find, sort, transform 등), 함수 객체(less, greater 등) 외에 이런저런 컨테이너 어댑터와 함수 객체 어댑터(stack, priority_queue, mem_fun, not1 등)가 있다. iostream 사용자 정의 버퍼링, 국제화 기능이 가능한 입출력을 지원하며, 그 외에 cin, cout, cerr, clog 등의 사전정의 객체를 지원한다. 국제화 지원 수치 처리 지..
53: 컴파일러 경고를 지나치지 말자 심각한 문제라면 에러가 나올 것이라고 생각하고 경고를 무시하면 안 된다. C++의 경우에는 우리가 저질러 놓은 코드가 어떤 것인가에 대해 컴파일러 제작자가 우리보다 더 잘 이해하기 있기를 바라는 것 자체가 큰 도박이다. class Base { public: virtual void f() const; }; class Derived : public Base { public: virtual void f(); }; 위의 코드는 가상 함수인 B::f 를 D::f 에서 재정의(redefine, 오버라이드)하겠다는 의도인데, 여기에 실수가 있다. B클래스의 f 함수는 상수 함수지만 Derived 클래스의 f는 괄호 뒤에 const가 없다. 이러면 책의 필자의 컴파일러는 다음과 같..
52: 위치지정 new를 작성한다면 위치지정 delete도 같이 준비하자 Widget* pw = new Widget; 위의 코드는 항목 17에서도 말했듯이, operator new와 Widget의 기본 생성자, 두 개의 함수가 실행된다. 여기서 두 번째 함수 호출이 진행되가가 예외가 발생했다고 가정하자. 이 경우 이미 끝난 메모리 할당을 취소하지 않으면 안된다. 사용자 코드에서는 이 메모리를 해제할 수 없다. 따라서 1단계의 메모리 할당을 안전하게 되돌리는 중대 임무는 C++ 런타임 시스템이 맡아 준다. C++ 런타임 시스템이 해 주어야 하는 일은 operator new와 짝이 맞는 버전의 operator delete를 호출하는 것이다. 우리가 사용하고 있던 기본 new, delete는 그다지 대수로운 ..
51: new 및 delete를 작성할 때 따라야 할 기존의 관례를 잘 알아 두자 operator new를 구현 하려면 다음의 요구사항만큼은 기본으로 지켜야 한다. 반환 값이 제대로 되어있어야 한다. 가용 메모리가 부족할 경우에는 new 처리자 함수를 호출해야 한다. 크기가 없는(0바이트) 메모리 요청에 대한 대비책을 갖춰야 한다. 실수로 "기본(normal)" 형태의 new가 가려지지 않도록 해야 한다. 반환 값 부분은 간단하다. 요청된 메모리를 마련해 줄 수 있으면 그 메모리에 대한 포인터를 반환하는 것으로 끝이다. 메모리를 마련해 줄 수 없을 때는, 항목 49에서 이야기한 규칙을 따라서 bad_alloc 타입의 예외를 던지게 하면 된다. 지금까지의 요구사항을 정리해서, 비멤버 버전의 operator..
50: new 및 delete를 언제 바꿔야 좋은 소리를 들을지를 파악해 두자 컴파일러의 기본 operator new와 operator delete를 바꾸고 싶은 가장 흔한 이유 세 가지를 보면 다음과 같다. 잘못된 힙 사용을 탐지하기 위해 new한 메모리에 delete를 잊으면 메모리가 누출된다. 두 번 이상 delete하면 미정의 동작이 발생한다. 만일 할당된 메모리 주소의 목록을 operator new가 유지해 두고 operator delete가 그 목록으로부터 주소를 하나씩 제거해 주게 만들어져 있다면, 이런 식의 실수는 쉽게 잡아낼 수 있을 것이다. 데이터 오버런(overrun) 및 언더런(underrun)을 대비하여 operator new를 활용한다면, 요구된 크기보다 약간 더 메모리를 할당한..
49: new 처리자의 동작 원리를 제대로 이해하자 메모리 할당이 제대로 되지 못한 상황에 대한 반응으로 operator new가 예외를 던지기 전에, 이 함수가 사용자 쪽에서 지정할 수 있는 에러 처리 함수를 우선적으로 호출하도록 되어 있는데, 이 에러 처리 함수를 가리켜 new 처리자(new-handler)라고 한다. 표준 라이브러리에는 set_new_handler라는 함수가있다. void outOfMem() { std::cerr
48: 템플릿 메타프로그래밍, 하지 않겠는가? 템플릿 메타프로그래밍(template metaprogramming: TMP)은 컴파일 도중에 실행되는 템플릿 기반의 프로그램을 작성하는 일을 말한다. 템플릿 메타프로그램은 C++ 컴파일러가 실행시키는, C++로 만들어진 프로그램이다. TMP에는 엄청난 강점이 두 개나 있다. TMP를 쓰면 다른 방법으로는 까다롭거나 불가능한 일을 굉장히 쉽게 할 수 있다. 템플릿 메타프로그램은 C++ 컴파일이 진행되는 동안에 실행되기 때문에, 기존 작업을 런타임 영역에서 컴파일 타임 영역으로 전환할 수 있다. 몇몇 에러들을 컴파일 도중에 찾을 수 있다. 추가적으로, 모든 면에서 효율적일 여지가 많다. 실행 코드가 작아지고, 실행 시간도 짧아지며, 메모리도 적게 잡아먹는다. 항..
47: 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자 STL의 유틸리티라고 불리는 템플릿의 advance라는 템플릿을 보자. 이 템플릿은 지정된 반복자를 지정된 거리만큼 이동시키는 것이다. template void advance(IterT& iter, DistT d); STL 반복자는 지원하는 연산에 따라 다섯 개의 범주로 나뉜다. 입력 반복자(input iterator) 전진만 가능하고, 한 번에 한 칸씩만 이동하며, 자신이 가리키는 위치에서 읽기만 가능하다. 읽을 수 있는 횟수는 한 번뿐이다. 출력 반복자(output iterator) 입력 반복자와 비슷하지만 출력용인 점만 다르다. 쓰기만 가능하다. 순방향 반복자(forward iterator) 입력 반복자와 출력 반복자가 하는 일은 다 ..
46: 타입 변환이 바람직할 경우에는 비멤버 함수를 클래스 템플릿 안에 정의해 두자 항목 24에서 모든 매개변수에 대해 암시적 타입 변환이 되도록 만들기 위해서는 비멤버 함수밖에 방법이 없다고 했었다. 이번엔 템플릿의 영역에서 알아보자. template class Rational { public: Rational(const T& numerator = 0, const T& denominator = 1); const T numerator() const; const T denominator() const; }; template const Rational operator*(const Rational& lhs, const Rational& rhs) {...} Rational onHalf(1, 2); Rationa..
KANTAM
'C++/Effective C++' 카테고리의 글 목록