SlideShare a Scribd company logo
1 of 38
7-41. 템플릿 프로그래밍의 천릿길도 암시적 인터페이스와 컴파일 타임 다형성부터
• 위와 같은 함수가 있을 때 w가 swap, normalize, !=연산자, > 연산자
등을 지원해야만 함수가 정상적으로 동작할 것이다. 이것을 w에 대한
암시적 인터페이스라 한다.
• 또한 이 함수가 w와 함께 호출될 때 이 템플릿의 인스턴스화가
일어나는데, T가 어떤 타입이냐에 따라 다른 함수가 나와야하므로 이
인스턴스화는 컴파일이 진행될 때에야 발생한다. 이것을 컴파일 타임
다형성이라한다.
7-41. 템플릿 프로그래밍의 천릿길도 암시적 인터페이스와 컴파일 타임 다형성부터
• 반대로 위와 같이 명확히 헤더의 클래스 선언 등을 통해 확인할 수 있는
인터페이스를 명시적 인터페이스라 한다.
• 또한 이 클래스의 멤버인 가상함수가 호출될 때 어떤 함수가 호출될
것인지에 대한 것은 프로그램 실행 중에 결정된다. 이러한 경우를 런타임
다형성이라고 한다.
7-42. typename의 두 가지 의미를 제대로 파악하자
• 왼쪽과 같은 코드에서 컴파일러는
iterator가 타입인지 T클래스의
멤버 변수인지 알 수가 없다.
• 그래서 컴파일러는 저런 경우 일단
변수로 취급한다.
• 컴파일러에게 iterator타입이라
명시해주기 위해서는 왼쪽과 같이
typename을 붙여주어야 한다.
일반적으로 template<class T>와 template<typename T>는 차이가 없다.
다만 아래와 같은 경우 typename이 필요하다.
7-42. typename의 두 가지 의미를 제대로 파악하자
• std::iterator_traits<T>::value_type이란 T타입의 객체로 가리키는
대상의 타입이라는 의미이다.
• 즉, T타입의 객체가 가리키는 대상과 같은 타입의 temp를 선언하고
iter가 가리키는 객체로 temp를 초기화 해준다.
• 그런데… std::iterator_traits<T>::value_type …참 길다.
여러 번 사용해야 해서 불편할 경우 다음과 같이 typedef를 쓰자.
typedef typename std::iterator_traits<T>::value_type value_type;
value_type temp( *iter );
7-43. 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아 두자
왼쪽과 같은 클래스가 있다고 하자.
2번째 클래스는 제대로 작동하지 않는다.
컴파일러가 Derived를 마주쳤을 때
Tclass도 모르는 판에 Base가 무엇인지
정확히 알 방도가 없기 때문이다.
해결방법은 3가지가 있다.
7-43. 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아 두자
해결방법 3가지는 다음과 같다
• Func1() 대신 this->Func1()로 적어준다.
이렇게 해주면 Func1()이 상속되는 것으로 가정해준다.
• Func1()사용 전에 using Base<Tclass>::Func1;로 기본클래스에
Func1()함수의 존재를 명시해준다.
• Base<Tclass>::Func1();로 적어주어 상속된 함수임을 명시해준다.
다만 이 방법은 가상함수 바인딩이 무시되므로 추천하지 않는다.
7-43. 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아 두자
※주의
당연한 말이지만 저 같은 방법들을
쓰더라도
왼쪽과 같이 상속된 기본 템플릿
클래스가 특수화 되어서
Func1()을 지원하지 않는다면 컴파일
에러가 나게 된다.
7-44. 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자
템플릿 코드의 문제는 코드 중복이 암시적이라 잘 눈에 띄지 않다 보니,
컴파일 후 코드의 비대화가 발생하기 쉽다는 것이다.
좌측과 같이 n크기의 정방행렬을
만드는 템플릿 클래스의 경우를 보자.
단순히 5x5인가 10x10인가의 차이일
뿐이지만 SquareMatrix클래스는
2개가 생기게 된다.
7-44. 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자
좀 전 코드에서는
중복이 2개 뿐이었지만
숫자가 5, 10뿐 아니라
다른 숫자가 들어갈
때마다 그만큼 코드가
중복 생성되게 된다.
좌측과 같이 n과는
독립적인 공통부분을
분리하면 그러한 코드
중복을 방지할 수 있다.
7-44. 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자
하지만 좀 전 코드에도
문제가 보인다. invert 함수의
경우 실제 동작은 기본
클래스이지만 대상이 되는
행렬이 파생 클래스에 있게
된다.
이것을 해결하려면 좌측과
같이 파생클래스에서
기본클래스로 데이터를
포인터로 전달해주면 된다.
7-44. 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자
※주의
독립적인 템플릿 코드로 분리하면 코드의 크기는 줄어들지만 코드의
최적화 효과는 해칠 수 가 있다.
물론, 대부분의 경우 코드의 크기가 줄어들어 생기는 참조 지역성의
이점으로 최적화의 손해를 충분히 메꾸겠지만 그렇지 않은 경우도
충분히 있을 수 있으므로 상황에 맞게 사용하자.
7-45. “호환되는 모든 타입”을 받아들이는 데는 멤버 함수 템플릿이 직방!
예를 들어 기본제공 포인터의 경우, 파생클래스의 포인터는 기본클래스의
포인터로 암시적 변환이 가능하다.
또한 기타 호환되는 포인터들간의 암시적 변환들도 가능하다.
무수히 많은 타입들이 있을 수 있기에 이러한 기능을 사용자가 구현하려면
템플릿 없이는 사실상 불가능하다.
예를 들어 스마트 포인터를 만든다고 하자.
7-45. “호환되는 모든 타입”을 받아들이는 데는 멤버 함수 템플릿이 직방!
좌측과 같이 멤버 함수에
템플릿을 쓰면 기본 제공
포인터의 기능을 사용해 간단히
U라는 타입에서 T라는 타입으로
가능한 모든 변환을 지원할 수
있게 만들 수 있다.
템플릿이 없다면 모든 가능성에
대해 고려 해야하니 사실상
제대로 된 구현이 불가능하다.
7-46. 타입 변환이 바람직할 경우에는 비멤버 함수를 클래스 템플릿 안에 정의해 두자
비멤버 함수를 사용한 이 코드는
템플릿이란 점만 제외하면
24항목에의 모든 매개변수에
대한 연산의 해결책과 동일한
방법이다.
Rational<int> oneHalf( 1, 2 );
Rational<int> result = oneHalf * 2;
그러나 좌측 코드에서 2번째
줄은 2에 대한 변환을 하지 못해
에러가 난다.
7-46. 타입 변환이 바람직할 경우에는 비멤버 함수를 클래스 템플릿 안에 정의해 두자
그런 경우 클래스 내에 friend로 선언해주면 컴파일러가 판별 가능하게 된다.
그러나 그래서는 정의 또한 클래스 내에 있지 않으면 링크 에러가 난다.
하지만 클래스 내의 함수 정의는 암시적 inline취급이므로 위와 같이
다시 외부의 함수를 호출하는 방법을 사용하여 해결해야 한다.
7-47. 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자
반복자를 임의의 숫자만큼 증가 시키는 함수를 구현한다고 하자.
우선 반복자는 5가지 타입이 있고, 이를 식별하기 위한 태그 구조체가 있다.
input_iterator_tag : 입력 반복자. 순방향으로 1회 입력 후 이동만 가능하다.
output_iterator_tag : 출력 반복자. 순방향으로 1회 출력 후 이동만 가능하다.
forward_iterator_tag : 순방향 반복자. 입력 반복자를 상속한다.
순방향 입출력이 여러 번 가능하다.
bidirectinal_iterator_tag : 양방향 반복자. 순방향 반복자를 상속한다.
양방향 입출력이 여러 번 가능하다.
random_access_iterator_tag : 임의 접근 반복자. 양방향 반복자를 상속한다.
양방향으로 임의의 거리 이동, 입출력이 여러 번 가능하다.
7-47. 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자
이러한 반복자 타입에 대한 정보를 얻는 것은 iterator_traits 라는 템플릿
구조체로 얻을 수 있다. 이러한 특성 정보는 구조체로 선언하는 것이 관례이며
부르기는 특성 정보 클래스라 부른다.
클래스 내부에서는 typedef를 사용해 다음과 같이 iterator_category로
나타낸다. (vector이므로 임의 접근 반복자이다.)
7-47. 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자
Iterator_traits에서는 해당 정보를 그대로 자신의 iterator_category로 가져와
처리한다.
다만 대상이 포인터일 경우에는 포인터 자체가 임의 접근 반복자와 같으므로
아래와 같이 특수화될 것이다.
7-47. 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자
이제 직접 작업할 함수를 만들자. 입력 반복자의 경우엔 아래와 같을 것이다.
이처럼 각 반복자 종류마다 함수를 오버로딩 해준 후,
아래와 같이 호출할 함수를 만들면 된다.
7-47. 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자
C++에는 TR1이후 이런 식의 특성 정보 클래스가 50개 넘는다.
( ex> is_array<T>, is_base_of<T1, T2>, 등등 )
타입에 대한 정보가 필요한 함수나 객체의 경우 지금까지 구현한 바와 같이
특성 정보 클래스로 얻은 특성 정보에 따라 작업부를 오버로딩하고 그 호출부를
만드는 것으로 구현해볼 수 있다.
7-48. 템플릿 메타프로그래밍, 하지 않겠는가?
템플릿 메타 프로그래밍(TMP)는 기존에 런타임에서 하던 작업을 컴파일
단계에서 수행할 수 있도록 하는 효과가 있다.
때문에 오류 탐지 또한 런타임에서 확인 될 부분을 컴파일 단계에서 확인하는
것이 가능하며,
런타임에서 실행 시 상당히 비용을 잡아먹는 작업을 컴파일 단계에서
끝내놓음으로써 코드의 크기와 속도를 향상시키는 것도 가능하다.
(※물론 이럴 경우 컴파일 타임은 증가하게 된다.)
7-48. 템플릿 메타프로그래밍, 하지 않겠는가?
예를 들어 피보나치 수를 구한다고 했을 때 TMP로 작성하면 아래와 같다.
이는 모두 컴파일
타임에 계산되어
실제 실행 시에는
계산 과정 없이
결과를 출력하게 된다.
7-48. 템플릿 메타프로그래밍, 하지 않겠는가?
TMP는 다음과 같은 분야에 사용될 수 있다.
• 단위(질량, 거리, 시간 등)의 정확성 확인
과학 기술 분야의 프로그램에서는 정확한 단위 조합이 바탕이 되어야 한다.
TMP는 이를 컴파일 단계에서 검사해볼 수 있다.
• 행렬 연산의 최적화
• 맞춤식 디자인 패턴 구현의 생성
typedef SquareMatrix<double, 10000> BigMatrix;
BigMatrix m1, m2, m3, m4, m5;
...
BigMatrix result = m1 * m2 * m3 * m4 * m5;
이러한 고비용 계산방식도
컴파일 시에 이미 처리하여
실행 시에는 최적화된 계산으로
빠르게 결과를 볼 수 있다.
8-49. new 처리자의 동작 원리를 제대로 이해하자
new연산에서 메모리 할당을 실패했을 때 예외를 던지기 전에 처리해줄 함수를
new_handler라고 하며, 이는 사용자가 지정(설치) 가능하다.
set_new_handler함수로 가능한데 이 함수는 새로운 new_handler의 포인터를
매개 변수로 받고 이전 new_handler를 반환한다.
new_handler에는 다음과 같은 종류가 있을 수 있다.
• 사용할 수 있는 메모리를 더 확보한다.
• 자신을 대신할 수 있는 다른 new 처리자를 설치한다.
• 설치된 new 처리자를 제거하여 예외를 던지게 한다.
• bad_alloc이나 그에서 파생된 타입의 예외를 원래의 요청 위치로 전달한다.
• 복귀하지 않고 그대로 abort나 exit 등을 호출한다.
8-49. new 처리자의 동작 원리를 제대로 이해하자
이와 같은 템플릿을
만들어 상속받으면
쉽게 클래스 별
set_new_handler를
제공할 수 있다.
이러한 식으로
자신을 매개변수로
넣은 템플릿을
자신이 상속받는
구조를 CRTP라고
한다.
※ CRTP : Curiously Recurring Template Pattern
8-49. new 처리자의 동작 원리를 제대로 이해하자
1993년까지는 new가 메모리 할당에 실패 시 null포인터를 반환 했지만 몇 년
후 부터는 bad_alloc 예외를 던지도록 되었다. 하지만 이미 null포인터 반환을
기반으로 작성된 프로그램이 많았기에 구 방식도 함께 지원을 하도록 했다.
이렇게 null포인터를 반환하는 구 방식을 “예외불가(nothrow)” 형태라고 한다.
class Widget { ... };
Widget *pw = new ( std::nothrow ) Widget;
if( pw == nullptr ){ ... }
이러한 사용이 가능하다.
다만 이러한 예외불가 지정은
일회성으로 할당 성공 후나 이후 다른
new까지 영향을 미치진 못한다.
8-50. new 및 delete를 언제 바꿔야 좋은 소리를 들을지를 파악해 두자
operator new와 operator delete를 변경하는 목적은 보통 3가지로 나뉜다.
 잘못된 힙 사용을 탐지한다.
- new된 메모리 주소를 목록화 시킨 후 delete가 목록을 순회한다면
delete를 빠트리거나 중복 delete 하는 경우를 막을 수 있다.
- 사용 메모리 시작과 끝에 오버런/언더런 탐지용 패턴을 넣어 검사하도록 할
수 도 있다.
 효율을 향상시킨다.
- 기본 제공되는 new는 안정성 지향이기에 특정상황에 특화되지는 못했다.
그러므로 최적화가 필요하다면 변경할 필요가 있다.
 동적 할당 메모리의 실제 사용 통계를 수집한다.
8-50. new 및 delete를 언제 바꿔야 좋은 소리를 들을지를 파악해 두자
그밖에 다음과 같은 목적들로도 쓰인다.
 기본 메모리 관리자의 공간 오버헤드를 줄인다.
 적당히 타협한 기본 할당자의 바이트 정렬 동작을 보장한다.
- 간혹 어떤 컴파일러는 double 동적 할당 시 8바이트 정렬을 보장하지 않는
경우도 있다. 이런 경우 new를 변경하여 성능 개선을 꾀할 수 있다.
 임의의 관계를 맺고 있는 객체들을 한 군데 모아놓는다.
- 대개 함께 쓰이는 특정 자료구조들이 있다면 위치 지정 new/delete를
이용하여 같은 page에 모아 page fault를 최소화 할 수 있다.
 그때그때 원하는 동작을 수행하도록 한다.
- 기본 new/delete가 제공하지 않는 기능을 수행하고 싶은 경우
※ 일반적인 경우, 변경하기 보다는 그냥 컴파일러의 기능이나 기타 유틸리티를 이용하자.
8-51. new 및 delete를 작성할 때 따라야 할 기존의 관례를 잘 알아 두자
new
• 반환 값이 제대로 되어 있을 것
- 할당 성공 시엔 포인터를 반환하면 끝.
- 할당 실패할 때마다 new 처리자를 호출 하여 메모리 할당을 시도해본다.
- new는 new 처리자 포인터가 null일 경우에만 bad_alloc예외를 던진다.
• 가용 메모리가 부족하면 new 처리자 함수를 호출할 것
• 크기가 없는(0 byte) 메모리 요청에 대비책을 갖출 것
• 기본 형태의 new가 가려지지 않도록 할 것
• 파생 클래스의 경우 기본 클래스의 new가 호출되어 잘못된 크기가 요청될 수
있으므로 대비책이 필요하다.
- 가장 간단한 해결책은 잘못된 크기가 들어올 경우 기본제공 new로 전환.
8-51. new 및 delete를 작성할 때 따라야 할 기존의 관례를 잘 알아 두자
delete
• null포인터에 대한 delete의 안전을 보장한다.
• 삭제될 메모리의 크기를 점검해본다.
- 역시 제일 간단한 해결책은 잘못된 크기일 경우 기본 제공 delete로 전환.
8-52. 위치지정 new를 작성한다면 위치지정 delete도 같이 준비하자
위와 같은 코드에서 사용자 지정 new가 호출되어 할당까지 성공했는데
Widget 생성자에서 예외가 발생할 경우 C++런타임 시스템에서 delete를
호출하게 된다.
헌데 사용자 지정으로 만든 new와 짝이 되는 delete가 존재하지 않는다면
호출하지 못해 메모리 누출이 발생한다.
하지만 코드가 정상적으로 성공하고 그 후 delete 코드가 있다면 기본형
delete가 호출된다.
즉, 위치지정 new가 있을 경우엔 기본형 delete와 위치지정 delete를 모두
마련해 두어야 한다.
Widget *pw = new (std::cerr) Widget;
8-53. 컴파일러 경고를 지나치지 말자
경고(warning) 메시지를 무시해서는 안 된다. 컴파일러는 절대로 당신보다
코드를 잘 이해하고 있지 않다.
좌측 코드의 경우
Warning: Derived::Func() hides virtual Base::Func()
라는 경고가 뜬다.
얼핏 당연한 소리를 경고하는거 같지만
const를 빠트렸기에 재선언된게 아니라
가려졌다고 경고하고 있는 것이다.
※주의
경고 메시지는 컴파일러에 따라 천차만별이다. 지나치게 의존해서는 안된다.
8-54. TR1을 포함한 표준 라이브러리 구성요소와 편안한 친구가 되자
C++98의 표준 C++라이브러리의 주요 구성 요소는 다음과 같다.
 표준 템플릿 라이브러리(STL: Standard Template Library)
 iostream : 사용자 정의 버퍼링, 국제화 기능 입출력, cin, cout, cerr 등.
 국제화 지원 : 여러 로케일(locale)과 유니코드(wchar_t, wstring) 지원.
 수치 처리 지원: 복소수 템플릿(complex), 수치배열 템플릿(valarray)등.
 예외 클래스 : exception 및 logic_error, runtime_error 등.
 C89의 표준 라이브러리
위의 요소들은 모두 익숙해야 한다.
8-54. TR1을 포함한 표준 라이브러리 구성요소와 편안한 친구가 되자
TR1의 요소들.
 스마트 포인터 : shared_ptr은 순환 구조에 빠지면 참조 카운트가 0이 안될
수 있다. weak_ptr은 이를 보완한 포인터이다.
 tr1::function : 어떤 함수의 시그니처와 호환되는 시그니처를 가진 함수호출
개체를 표현한다.
위의 코드들은 매개변수가 “int를 받고 string을 반환하는 함수”라는 선언이다.
 tr1::bind : STL의 bind1st, bind2nd와 같은 동작을 하며 좀더 많은
기능을 제공한다. 상수와 비상수 멤버에 상관 없이 동작가능하며, 외부 보조
없이도 함수 포인터를 다룰 수 있다.
void regCallBack( std::string func( int ) );
void regCallBack( std::string ( int ) );
8-54. TR1을 포함한 표준 라이브러리 구성요소와 편안한 친구가 되자
 해시 테이블 : 해시 테이블을 기반으로 세트, 맵, 멀티맵등이 구현되었다.
tr1::unordered_set, tr1::unordered_multiset,
tr1::unordered_map, tr1::unordered_multimap.
 정규 표현식 : 정규 표현식 기반의 탐색, 대체 연산등이 가능해졌다.
 투플 : pair와 비슷하지만 2개이상 몇 개라도 담을 수 있다.
 tr1::array : “STL스럽게 된” 배열.
 tr1::mem_fn : 멤버 함수 포인터를 adapt시키는 용도. mem_fun,
mem_fun_ref 등의 발전형.
 tr1::reference_wrapper : 기존의 참조자를 객체처럼 다룰 수 있게 해준다.
 난수 발생 : 기존 rand의 발전형.
 특수 용도의 수학 함수 : 라게르 다항식, 베셀 함수, 완전 타원 적분 등.
8-54. TR1을 포함한 표준 라이브러리 구성요소와 편안한 친구가 되자
 C99 호환성 확장 기능 : C99의 라이브러리를 C++로 가져오기위한 함수 및
템플릿.
 타입 특성정보 : 항목 47에서 다뤘던 특성정보 클래스의 모음.
그 외에도 가상 소멸자 지원 여부에서 적절한 바이트
정렬까지도 알 수 있다.
 tr1::result_of : 어떤 함수 호출의 반환 타입을 추론한다.
템플릿 프로그래밍에서는 반환타입이 달라질 수 있지만
이 템플릿으로 반환타입 참조를 쉽게 할 수 있다.
8-55. Boo子有親! 부스트를 늘 여러분 가까이에
부스트는 C++개발자들의 단체이자 무료 C++라이브러리 집합을 일컫는다.
C++표준화 위원회와도 밀접하고 영향력이 있다 보니 사실상 표준화 전의
테스트 장소라고도 볼 수 있다.
공개 동료 심사 시스템에 의해 자격 미달의 라이브러리가 발을 들여놓는 것이
효과적으로 차단되고 있고, 업계 수준의 교차 플랫폼 라이브러리의
설계·구현·문서화 방법이 자연스럽게 전수되고 있다.
다양한 규모의 다양한 라이브러리가 제공되어 유용한 것들이 많다.
http://boost.org
8-55. Boo子有親! 부스트를 늘 여러분 가까이에
 문자열 및 텍스트 처리
 컨테이너
 함수 객체 및 고차 프로그래밍
 일반화 프로그래밍
 템플릿 메타프로그래밍
 수학 및 수치 조작
 정확성 유지 테스트
 자료구조
 타 언어 연동 지원
 메모리
… 등의 다양한 분야를 지원한다.

More Related Content

What's hot

Effective c++ Chapter1,2
Effective c++ Chapter1,2Effective c++ Chapter1,2
Effective c++ Chapter1,2문익 장
 
More effective c++ 2
More effective c++ 2More effective c++ 2
More effective c++ 2현찬 양
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Nam Hyeonuk
 
More effective c++ 항목30부터
More effective c++ 항목30부터More effective c++ 항목30부터
More effective c++ 항목30부터Dong Chan Shin
 
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++Min-soo Park
 
Effective c++ chapter3, 4 요약본
Effective c++ chapter3, 4 요약본Effective c++ chapter3, 4 요약본
Effective c++ chapter3, 4 요약본Dong Chan Shin
 
Effective c++chapter3
Effective c++chapter3Effective c++chapter3
Effective c++chapter3성연 김
 
Effective c++ 1,2
Effective c++ 1,2Effective c++ 1,2
Effective c++ 1,2세빈 정
 
Effective c++chapter8
Effective c++chapter8Effective c++chapter8
Effective c++chapter8성연 김
 
Effective c++chapter4
Effective c++chapter4Effective c++chapter4
Effective c++chapter4성연 김
 
Effective c++chapter1 and2
Effective c++chapter1 and2Effective c++chapter1 and2
Effective c++chapter1 and2성연 김
 
Effective c++ 정리 1~2
Effective c++ 정리 1~2Effective c++ 정리 1~2
Effective c++ 정리 1~2Injae Lee
 
More effective c++ 1
More effective c++ 1More effective c++ 1
More effective c++ 1현찬 양
 
Effective c++ 2
Effective c++ 2Effective c++ 2
Effective c++ 2현찬 양
 
Effective c++ 1
Effective c++ 1Effective c++ 1
Effective c++ 1현찬 양
 
More effective c++ 3
More effective c++ 3More effective c++ 3
More effective c++ 3현찬 양
 
Effective C++ Chaper 1
Effective C++ Chaper 1Effective C++ Chaper 1
Effective C++ Chaper 1연우 김
 
모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디quxn6
 
Start IoT with JavaScript - 1.기초
Start IoT with JavaScript - 1.기초Start IoT with JavaScript - 1.기초
Start IoT with JavaScript - 1.기초Park Jonggun
 
The C++ Programming Language 5장 포인터, 배열, 구조체
The C++ Programming Language 5장 포인터, 배열, 구조체The C++ Programming Language 5장 포인터, 배열, 구조체
The C++ Programming Language 5장 포인터, 배열, 구조체해강
 

What's hot (20)

Effective c++ Chapter1,2
Effective c++ Chapter1,2Effective c++ Chapter1,2
Effective c++ Chapter1,2
 
More effective c++ 2
More effective c++ 2More effective c++ 2
More effective c++ 2
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약
 
More effective c++ 항목30부터
More effective c++ 항목30부터More effective c++ 항목30부터
More effective c++ 항목30부터
 
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
 
Effective c++ chapter3, 4 요약본
Effective c++ chapter3, 4 요약본Effective c++ chapter3, 4 요약본
Effective c++ chapter3, 4 요약본
 
Effective c++chapter3
Effective c++chapter3Effective c++chapter3
Effective c++chapter3
 
Effective c++ 1,2
Effective c++ 1,2Effective c++ 1,2
Effective c++ 1,2
 
Effective c++chapter8
Effective c++chapter8Effective c++chapter8
Effective c++chapter8
 
Effective c++chapter4
Effective c++chapter4Effective c++chapter4
Effective c++chapter4
 
Effective c++chapter1 and2
Effective c++chapter1 and2Effective c++chapter1 and2
Effective c++chapter1 and2
 
Effective c++ 정리 1~2
Effective c++ 정리 1~2Effective c++ 정리 1~2
Effective c++ 정리 1~2
 
More effective c++ 1
More effective c++ 1More effective c++ 1
More effective c++ 1
 
Effective c++ 2
Effective c++ 2Effective c++ 2
Effective c++ 2
 
Effective c++ 1
Effective c++ 1Effective c++ 1
Effective c++ 1
 
More effective c++ 3
More effective c++ 3More effective c++ 3
More effective c++ 3
 
Effective C++ Chaper 1
Effective C++ Chaper 1Effective C++ Chaper 1
Effective C++ Chaper 1
 
모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디
 
Start IoT with JavaScript - 1.기초
Start IoT with JavaScript - 1.기초Start IoT with JavaScript - 1.기초
Start IoT with JavaScript - 1.기초
 
The C++ Programming Language 5장 포인터, 배열, 구조체
The C++ Programming Language 5장 포인터, 배열, 구조체The C++ Programming Language 5장 포인터, 배열, 구조체
The C++ Programming Language 5장 포인터, 배열, 구조체
 

Similar to 이펙티브 C++ (7~9)

Chapter7~9 ppt
Chapter7~9 pptChapter7~9 ppt
Chapter7~9 pptInjae Lee
 
Effective c++ chapter 7,8
Effective c++ chapter 7,8Effective c++ chapter 7,8
Effective c++ chapter 7,8문익 장
 
이펙티브 C++ 789 공부
이펙티브 C++ 789 공부이펙티브 C++ 789 공부
이펙티브 C++ 789 공부quxn6
 
Effective c++ chapter7_8_9_dcshin
Effective c++ chapter7_8_9_dcshinEffective c++ chapter7_8_9_dcshin
Effective c++ chapter7_8_9_dcshinDong Chan Shin
 
Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장 Shin heemin
 
Template at c++
Template at c++Template at c++
Template at c++Lusain Kim
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심흥배 최
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Ryan Park
 
카사 공개세미나1회 W.E.L.C.
카사 공개세미나1회  W.E.L.C.카사 공개세미나1회  W.E.L.C.
카사 공개세미나1회 W.E.L.C.Ryan Park
 
Chapter5 ~ 6
Chapter5 ~ 6Chapter5 ~ 6
Chapter5 ~ 6Injae Lee
 
Programming java day2
Programming java day2Programming java day2
Programming java day2Jaehoonyam
 
[C언어]함수오버로딩과오버라이딩
[C언어]함수오버로딩과오버라이딩[C언어]함수오버로딩과오버라이딩
[C언어]함수오버로딩과오버라이딩jusingame
 
[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java유리 하
 
2014-15 Intermediate C++ Study #7
2014-15 Intermediate C++ Study #72014-15 Intermediate C++ Study #7
2014-15 Intermediate C++ Study #7Chris Ohk
 
Effective STL 1~4장 정리
Effective STL 1~4장 정리Effective STL 1~4장 정리
Effective STL 1~4장 정리Shin heemin
 
[아꿈사] The C++ Programming Language 13장 템플릿
[아꿈사] The C++ Programming Language 13장 템플릿[아꿈사] The C++ Programming Language 13장 템플릿
[아꿈사] The C++ Programming Language 13장 템플릿해강
 
XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"
XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"
XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"XpressEngine
 

Similar to 이펙티브 C++ (7~9) (20)

EC 789
EC 789EC 789
EC 789
 
Chapter7~9 ppt
Chapter7~9 pptChapter7~9 ppt
Chapter7~9 ppt
 
Effective c++ chapter 7,8
Effective c++ chapter 7,8Effective c++ chapter 7,8
Effective c++ chapter 7,8
 
이펙티브 C++ 789 공부
이펙티브 C++ 789 공부이펙티브 C++ 789 공부
이펙티브 C++ 789 공부
 
Effective c++ chapter7_8_9_dcshin
Effective c++ chapter7_8_9_dcshinEffective c++ chapter7_8_9_dcshin
Effective c++ chapter7_8_9_dcshin
 
7 8 1
7 8 17 8 1
7 8 1
 
Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장
 
Template at c++
Template at c++Template at c++
Template at c++
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심
 
Exception&log
Exception&logException&log
Exception&log
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005
 
카사 공개세미나1회 W.E.L.C.
카사 공개세미나1회  W.E.L.C.카사 공개세미나1회  W.E.L.C.
카사 공개세미나1회 W.E.L.C.
 
Chapter5 ~ 6
Chapter5 ~ 6Chapter5 ~ 6
Chapter5 ~ 6
 
Programming java day2
Programming java day2Programming java day2
Programming java day2
 
[C언어]함수오버로딩과오버라이딩
[C언어]함수오버로딩과오버라이딩[C언어]함수오버로딩과오버라이딩
[C언어]함수오버로딩과오버라이딩
 
[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java
 
2014-15 Intermediate C++ Study #7
2014-15 Intermediate C++ Study #72014-15 Intermediate C++ Study #7
2014-15 Intermediate C++ Study #7
 
Effective STL 1~4장 정리
Effective STL 1~4장 정리Effective STL 1~4장 정리
Effective STL 1~4장 정리
 
[아꿈사] The C++ Programming Language 13장 템플릿
[아꿈사] The C++ Programming Language 13장 템플릿[아꿈사] The C++ Programming Language 13장 템플릿
[아꿈사] The C++ Programming Language 13장 템플릿
 
XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"
XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"
XE 오픈 세미나(2014-04-26) - 김동현 "XE 코어 구조론"
 

이펙티브 C++ (7~9)

  • 1. 7-41. 템플릿 프로그래밍의 천릿길도 암시적 인터페이스와 컴파일 타임 다형성부터 • 위와 같은 함수가 있을 때 w가 swap, normalize, !=연산자, > 연산자 등을 지원해야만 함수가 정상적으로 동작할 것이다. 이것을 w에 대한 암시적 인터페이스라 한다. • 또한 이 함수가 w와 함께 호출될 때 이 템플릿의 인스턴스화가 일어나는데, T가 어떤 타입이냐에 따라 다른 함수가 나와야하므로 이 인스턴스화는 컴파일이 진행될 때에야 발생한다. 이것을 컴파일 타임 다형성이라한다.
  • 2. 7-41. 템플릿 프로그래밍의 천릿길도 암시적 인터페이스와 컴파일 타임 다형성부터 • 반대로 위와 같이 명확히 헤더의 클래스 선언 등을 통해 확인할 수 있는 인터페이스를 명시적 인터페이스라 한다. • 또한 이 클래스의 멤버인 가상함수가 호출될 때 어떤 함수가 호출될 것인지에 대한 것은 프로그램 실행 중에 결정된다. 이러한 경우를 런타임 다형성이라고 한다.
  • 3. 7-42. typename의 두 가지 의미를 제대로 파악하자 • 왼쪽과 같은 코드에서 컴파일러는 iterator가 타입인지 T클래스의 멤버 변수인지 알 수가 없다. • 그래서 컴파일러는 저런 경우 일단 변수로 취급한다. • 컴파일러에게 iterator타입이라 명시해주기 위해서는 왼쪽과 같이 typename을 붙여주어야 한다. 일반적으로 template<class T>와 template<typename T>는 차이가 없다. 다만 아래와 같은 경우 typename이 필요하다.
  • 4. 7-42. typename의 두 가지 의미를 제대로 파악하자 • std::iterator_traits<T>::value_type이란 T타입의 객체로 가리키는 대상의 타입이라는 의미이다. • 즉, T타입의 객체가 가리키는 대상과 같은 타입의 temp를 선언하고 iter가 가리키는 객체로 temp를 초기화 해준다. • 그런데… std::iterator_traits<T>::value_type …참 길다. 여러 번 사용해야 해서 불편할 경우 다음과 같이 typedef를 쓰자. typedef typename std::iterator_traits<T>::value_type value_type; value_type temp( *iter );
  • 5. 7-43. 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아 두자 왼쪽과 같은 클래스가 있다고 하자. 2번째 클래스는 제대로 작동하지 않는다. 컴파일러가 Derived를 마주쳤을 때 Tclass도 모르는 판에 Base가 무엇인지 정확히 알 방도가 없기 때문이다. 해결방법은 3가지가 있다.
  • 6. 7-43. 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아 두자 해결방법 3가지는 다음과 같다 • Func1() 대신 this->Func1()로 적어준다. 이렇게 해주면 Func1()이 상속되는 것으로 가정해준다. • Func1()사용 전에 using Base<Tclass>::Func1;로 기본클래스에 Func1()함수의 존재를 명시해준다. • Base<Tclass>::Func1();로 적어주어 상속된 함수임을 명시해준다. 다만 이 방법은 가상함수 바인딩이 무시되므로 추천하지 않는다.
  • 7. 7-43. 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아 두자 ※주의 당연한 말이지만 저 같은 방법들을 쓰더라도 왼쪽과 같이 상속된 기본 템플릿 클래스가 특수화 되어서 Func1()을 지원하지 않는다면 컴파일 에러가 나게 된다.
  • 8. 7-44. 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자 템플릿 코드의 문제는 코드 중복이 암시적이라 잘 눈에 띄지 않다 보니, 컴파일 후 코드의 비대화가 발생하기 쉽다는 것이다. 좌측과 같이 n크기의 정방행렬을 만드는 템플릿 클래스의 경우를 보자. 단순히 5x5인가 10x10인가의 차이일 뿐이지만 SquareMatrix클래스는 2개가 생기게 된다.
  • 9. 7-44. 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자 좀 전 코드에서는 중복이 2개 뿐이었지만 숫자가 5, 10뿐 아니라 다른 숫자가 들어갈 때마다 그만큼 코드가 중복 생성되게 된다. 좌측과 같이 n과는 독립적인 공통부분을 분리하면 그러한 코드 중복을 방지할 수 있다.
  • 10. 7-44. 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자 하지만 좀 전 코드에도 문제가 보인다. invert 함수의 경우 실제 동작은 기본 클래스이지만 대상이 되는 행렬이 파생 클래스에 있게 된다. 이것을 해결하려면 좌측과 같이 파생클래스에서 기본클래스로 데이터를 포인터로 전달해주면 된다.
  • 11. 7-44. 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자 ※주의 독립적인 템플릿 코드로 분리하면 코드의 크기는 줄어들지만 코드의 최적화 효과는 해칠 수 가 있다. 물론, 대부분의 경우 코드의 크기가 줄어들어 생기는 참조 지역성의 이점으로 최적화의 손해를 충분히 메꾸겠지만 그렇지 않은 경우도 충분히 있을 수 있으므로 상황에 맞게 사용하자.
  • 12. 7-45. “호환되는 모든 타입”을 받아들이는 데는 멤버 함수 템플릿이 직방! 예를 들어 기본제공 포인터의 경우, 파생클래스의 포인터는 기본클래스의 포인터로 암시적 변환이 가능하다. 또한 기타 호환되는 포인터들간의 암시적 변환들도 가능하다. 무수히 많은 타입들이 있을 수 있기에 이러한 기능을 사용자가 구현하려면 템플릿 없이는 사실상 불가능하다. 예를 들어 스마트 포인터를 만든다고 하자.
  • 13. 7-45. “호환되는 모든 타입”을 받아들이는 데는 멤버 함수 템플릿이 직방! 좌측과 같이 멤버 함수에 템플릿을 쓰면 기본 제공 포인터의 기능을 사용해 간단히 U라는 타입에서 T라는 타입으로 가능한 모든 변환을 지원할 수 있게 만들 수 있다. 템플릿이 없다면 모든 가능성에 대해 고려 해야하니 사실상 제대로 된 구현이 불가능하다.
  • 14. 7-46. 타입 변환이 바람직할 경우에는 비멤버 함수를 클래스 템플릿 안에 정의해 두자 비멤버 함수를 사용한 이 코드는 템플릿이란 점만 제외하면 24항목에의 모든 매개변수에 대한 연산의 해결책과 동일한 방법이다. Rational<int> oneHalf( 1, 2 ); Rational<int> result = oneHalf * 2; 그러나 좌측 코드에서 2번째 줄은 2에 대한 변환을 하지 못해 에러가 난다.
  • 15. 7-46. 타입 변환이 바람직할 경우에는 비멤버 함수를 클래스 템플릿 안에 정의해 두자 그런 경우 클래스 내에 friend로 선언해주면 컴파일러가 판별 가능하게 된다. 그러나 그래서는 정의 또한 클래스 내에 있지 않으면 링크 에러가 난다. 하지만 클래스 내의 함수 정의는 암시적 inline취급이므로 위와 같이 다시 외부의 함수를 호출하는 방법을 사용하여 해결해야 한다.
  • 16. 7-47. 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자 반복자를 임의의 숫자만큼 증가 시키는 함수를 구현한다고 하자. 우선 반복자는 5가지 타입이 있고, 이를 식별하기 위한 태그 구조체가 있다. input_iterator_tag : 입력 반복자. 순방향으로 1회 입력 후 이동만 가능하다. output_iterator_tag : 출력 반복자. 순방향으로 1회 출력 후 이동만 가능하다. forward_iterator_tag : 순방향 반복자. 입력 반복자를 상속한다. 순방향 입출력이 여러 번 가능하다. bidirectinal_iterator_tag : 양방향 반복자. 순방향 반복자를 상속한다. 양방향 입출력이 여러 번 가능하다. random_access_iterator_tag : 임의 접근 반복자. 양방향 반복자를 상속한다. 양방향으로 임의의 거리 이동, 입출력이 여러 번 가능하다.
  • 17. 7-47. 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자 이러한 반복자 타입에 대한 정보를 얻는 것은 iterator_traits 라는 템플릿 구조체로 얻을 수 있다. 이러한 특성 정보는 구조체로 선언하는 것이 관례이며 부르기는 특성 정보 클래스라 부른다. 클래스 내부에서는 typedef를 사용해 다음과 같이 iterator_category로 나타낸다. (vector이므로 임의 접근 반복자이다.)
  • 18. 7-47. 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자 Iterator_traits에서는 해당 정보를 그대로 자신의 iterator_category로 가져와 처리한다. 다만 대상이 포인터일 경우에는 포인터 자체가 임의 접근 반복자와 같으므로 아래와 같이 특수화될 것이다.
  • 19. 7-47. 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자 이제 직접 작업할 함수를 만들자. 입력 반복자의 경우엔 아래와 같을 것이다. 이처럼 각 반복자 종류마다 함수를 오버로딩 해준 후, 아래와 같이 호출할 함수를 만들면 된다.
  • 20. 7-47. 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자 C++에는 TR1이후 이런 식의 특성 정보 클래스가 50개 넘는다. ( ex> is_array<T>, is_base_of<T1, T2>, 등등 ) 타입에 대한 정보가 필요한 함수나 객체의 경우 지금까지 구현한 바와 같이 특성 정보 클래스로 얻은 특성 정보에 따라 작업부를 오버로딩하고 그 호출부를 만드는 것으로 구현해볼 수 있다.
  • 21. 7-48. 템플릿 메타프로그래밍, 하지 않겠는가? 템플릿 메타 프로그래밍(TMP)는 기존에 런타임에서 하던 작업을 컴파일 단계에서 수행할 수 있도록 하는 효과가 있다. 때문에 오류 탐지 또한 런타임에서 확인 될 부분을 컴파일 단계에서 확인하는 것이 가능하며, 런타임에서 실행 시 상당히 비용을 잡아먹는 작업을 컴파일 단계에서 끝내놓음으로써 코드의 크기와 속도를 향상시키는 것도 가능하다. (※물론 이럴 경우 컴파일 타임은 증가하게 된다.)
  • 22. 7-48. 템플릿 메타프로그래밍, 하지 않겠는가? 예를 들어 피보나치 수를 구한다고 했을 때 TMP로 작성하면 아래와 같다. 이는 모두 컴파일 타임에 계산되어 실제 실행 시에는 계산 과정 없이 결과를 출력하게 된다.
  • 23. 7-48. 템플릿 메타프로그래밍, 하지 않겠는가? TMP는 다음과 같은 분야에 사용될 수 있다. • 단위(질량, 거리, 시간 등)의 정확성 확인 과학 기술 분야의 프로그램에서는 정확한 단위 조합이 바탕이 되어야 한다. TMP는 이를 컴파일 단계에서 검사해볼 수 있다. • 행렬 연산의 최적화 • 맞춤식 디자인 패턴 구현의 생성 typedef SquareMatrix<double, 10000> BigMatrix; BigMatrix m1, m2, m3, m4, m5; ... BigMatrix result = m1 * m2 * m3 * m4 * m5; 이러한 고비용 계산방식도 컴파일 시에 이미 처리하여 실행 시에는 최적화된 계산으로 빠르게 결과를 볼 수 있다.
  • 24. 8-49. new 처리자의 동작 원리를 제대로 이해하자 new연산에서 메모리 할당을 실패했을 때 예외를 던지기 전에 처리해줄 함수를 new_handler라고 하며, 이는 사용자가 지정(설치) 가능하다. set_new_handler함수로 가능한데 이 함수는 새로운 new_handler의 포인터를 매개 변수로 받고 이전 new_handler를 반환한다. new_handler에는 다음과 같은 종류가 있을 수 있다. • 사용할 수 있는 메모리를 더 확보한다. • 자신을 대신할 수 있는 다른 new 처리자를 설치한다. • 설치된 new 처리자를 제거하여 예외를 던지게 한다. • bad_alloc이나 그에서 파생된 타입의 예외를 원래의 요청 위치로 전달한다. • 복귀하지 않고 그대로 abort나 exit 등을 호출한다.
  • 25. 8-49. new 처리자의 동작 원리를 제대로 이해하자 이와 같은 템플릿을 만들어 상속받으면 쉽게 클래스 별 set_new_handler를 제공할 수 있다. 이러한 식으로 자신을 매개변수로 넣은 템플릿을 자신이 상속받는 구조를 CRTP라고 한다. ※ CRTP : Curiously Recurring Template Pattern
  • 26. 8-49. new 처리자의 동작 원리를 제대로 이해하자 1993년까지는 new가 메모리 할당에 실패 시 null포인터를 반환 했지만 몇 년 후 부터는 bad_alloc 예외를 던지도록 되었다. 하지만 이미 null포인터 반환을 기반으로 작성된 프로그램이 많았기에 구 방식도 함께 지원을 하도록 했다. 이렇게 null포인터를 반환하는 구 방식을 “예외불가(nothrow)” 형태라고 한다. class Widget { ... }; Widget *pw = new ( std::nothrow ) Widget; if( pw == nullptr ){ ... } 이러한 사용이 가능하다. 다만 이러한 예외불가 지정은 일회성으로 할당 성공 후나 이후 다른 new까지 영향을 미치진 못한다.
  • 27. 8-50. new 및 delete를 언제 바꿔야 좋은 소리를 들을지를 파악해 두자 operator new와 operator delete를 변경하는 목적은 보통 3가지로 나뉜다.  잘못된 힙 사용을 탐지한다. - new된 메모리 주소를 목록화 시킨 후 delete가 목록을 순회한다면 delete를 빠트리거나 중복 delete 하는 경우를 막을 수 있다. - 사용 메모리 시작과 끝에 오버런/언더런 탐지용 패턴을 넣어 검사하도록 할 수 도 있다.  효율을 향상시킨다. - 기본 제공되는 new는 안정성 지향이기에 특정상황에 특화되지는 못했다. 그러므로 최적화가 필요하다면 변경할 필요가 있다.  동적 할당 메모리의 실제 사용 통계를 수집한다.
  • 28. 8-50. new 및 delete를 언제 바꿔야 좋은 소리를 들을지를 파악해 두자 그밖에 다음과 같은 목적들로도 쓰인다.  기본 메모리 관리자의 공간 오버헤드를 줄인다.  적당히 타협한 기본 할당자의 바이트 정렬 동작을 보장한다. - 간혹 어떤 컴파일러는 double 동적 할당 시 8바이트 정렬을 보장하지 않는 경우도 있다. 이런 경우 new를 변경하여 성능 개선을 꾀할 수 있다.  임의의 관계를 맺고 있는 객체들을 한 군데 모아놓는다. - 대개 함께 쓰이는 특정 자료구조들이 있다면 위치 지정 new/delete를 이용하여 같은 page에 모아 page fault를 최소화 할 수 있다.  그때그때 원하는 동작을 수행하도록 한다. - 기본 new/delete가 제공하지 않는 기능을 수행하고 싶은 경우 ※ 일반적인 경우, 변경하기 보다는 그냥 컴파일러의 기능이나 기타 유틸리티를 이용하자.
  • 29. 8-51. new 및 delete를 작성할 때 따라야 할 기존의 관례를 잘 알아 두자 new • 반환 값이 제대로 되어 있을 것 - 할당 성공 시엔 포인터를 반환하면 끝. - 할당 실패할 때마다 new 처리자를 호출 하여 메모리 할당을 시도해본다. - new는 new 처리자 포인터가 null일 경우에만 bad_alloc예외를 던진다. • 가용 메모리가 부족하면 new 처리자 함수를 호출할 것 • 크기가 없는(0 byte) 메모리 요청에 대비책을 갖출 것 • 기본 형태의 new가 가려지지 않도록 할 것 • 파생 클래스의 경우 기본 클래스의 new가 호출되어 잘못된 크기가 요청될 수 있으므로 대비책이 필요하다. - 가장 간단한 해결책은 잘못된 크기가 들어올 경우 기본제공 new로 전환.
  • 30. 8-51. new 및 delete를 작성할 때 따라야 할 기존의 관례를 잘 알아 두자 delete • null포인터에 대한 delete의 안전을 보장한다. • 삭제될 메모리의 크기를 점검해본다. - 역시 제일 간단한 해결책은 잘못된 크기일 경우 기본 제공 delete로 전환.
  • 31. 8-52. 위치지정 new를 작성한다면 위치지정 delete도 같이 준비하자 위와 같은 코드에서 사용자 지정 new가 호출되어 할당까지 성공했는데 Widget 생성자에서 예외가 발생할 경우 C++런타임 시스템에서 delete를 호출하게 된다. 헌데 사용자 지정으로 만든 new와 짝이 되는 delete가 존재하지 않는다면 호출하지 못해 메모리 누출이 발생한다. 하지만 코드가 정상적으로 성공하고 그 후 delete 코드가 있다면 기본형 delete가 호출된다. 즉, 위치지정 new가 있을 경우엔 기본형 delete와 위치지정 delete를 모두 마련해 두어야 한다. Widget *pw = new (std::cerr) Widget;
  • 32. 8-53. 컴파일러 경고를 지나치지 말자 경고(warning) 메시지를 무시해서는 안 된다. 컴파일러는 절대로 당신보다 코드를 잘 이해하고 있지 않다. 좌측 코드의 경우 Warning: Derived::Func() hides virtual Base::Func() 라는 경고가 뜬다. 얼핏 당연한 소리를 경고하는거 같지만 const를 빠트렸기에 재선언된게 아니라 가려졌다고 경고하고 있는 것이다. ※주의 경고 메시지는 컴파일러에 따라 천차만별이다. 지나치게 의존해서는 안된다.
  • 33. 8-54. TR1을 포함한 표준 라이브러리 구성요소와 편안한 친구가 되자 C++98의 표준 C++라이브러리의 주요 구성 요소는 다음과 같다.  표준 템플릿 라이브러리(STL: Standard Template Library)  iostream : 사용자 정의 버퍼링, 국제화 기능 입출력, cin, cout, cerr 등.  국제화 지원 : 여러 로케일(locale)과 유니코드(wchar_t, wstring) 지원.  수치 처리 지원: 복소수 템플릿(complex), 수치배열 템플릿(valarray)등.  예외 클래스 : exception 및 logic_error, runtime_error 등.  C89의 표준 라이브러리 위의 요소들은 모두 익숙해야 한다.
  • 34. 8-54. TR1을 포함한 표준 라이브러리 구성요소와 편안한 친구가 되자 TR1의 요소들.  스마트 포인터 : shared_ptr은 순환 구조에 빠지면 참조 카운트가 0이 안될 수 있다. weak_ptr은 이를 보완한 포인터이다.  tr1::function : 어떤 함수의 시그니처와 호환되는 시그니처를 가진 함수호출 개체를 표현한다. 위의 코드들은 매개변수가 “int를 받고 string을 반환하는 함수”라는 선언이다.  tr1::bind : STL의 bind1st, bind2nd와 같은 동작을 하며 좀더 많은 기능을 제공한다. 상수와 비상수 멤버에 상관 없이 동작가능하며, 외부 보조 없이도 함수 포인터를 다룰 수 있다. void regCallBack( std::string func( int ) ); void regCallBack( std::string ( int ) );
  • 35. 8-54. TR1을 포함한 표준 라이브러리 구성요소와 편안한 친구가 되자  해시 테이블 : 해시 테이블을 기반으로 세트, 맵, 멀티맵등이 구현되었다. tr1::unordered_set, tr1::unordered_multiset, tr1::unordered_map, tr1::unordered_multimap.  정규 표현식 : 정규 표현식 기반의 탐색, 대체 연산등이 가능해졌다.  투플 : pair와 비슷하지만 2개이상 몇 개라도 담을 수 있다.  tr1::array : “STL스럽게 된” 배열.  tr1::mem_fn : 멤버 함수 포인터를 adapt시키는 용도. mem_fun, mem_fun_ref 등의 발전형.  tr1::reference_wrapper : 기존의 참조자를 객체처럼 다룰 수 있게 해준다.  난수 발생 : 기존 rand의 발전형.  특수 용도의 수학 함수 : 라게르 다항식, 베셀 함수, 완전 타원 적분 등.
  • 36. 8-54. TR1을 포함한 표준 라이브러리 구성요소와 편안한 친구가 되자  C99 호환성 확장 기능 : C99의 라이브러리를 C++로 가져오기위한 함수 및 템플릿.  타입 특성정보 : 항목 47에서 다뤘던 특성정보 클래스의 모음. 그 외에도 가상 소멸자 지원 여부에서 적절한 바이트 정렬까지도 알 수 있다.  tr1::result_of : 어떤 함수 호출의 반환 타입을 추론한다. 템플릿 프로그래밍에서는 반환타입이 달라질 수 있지만 이 템플릿으로 반환타입 참조를 쉽게 할 수 있다.
  • 37. 8-55. Boo子有親! 부스트를 늘 여러분 가까이에 부스트는 C++개발자들의 단체이자 무료 C++라이브러리 집합을 일컫는다. C++표준화 위원회와도 밀접하고 영향력이 있다 보니 사실상 표준화 전의 테스트 장소라고도 볼 수 있다. 공개 동료 심사 시스템에 의해 자격 미달의 라이브러리가 발을 들여놓는 것이 효과적으로 차단되고 있고, 업계 수준의 교차 플랫폼 라이브러리의 설계·구현·문서화 방법이 자연스럽게 전수되고 있다. 다양한 규모의 다양한 라이브러리가 제공되어 유용한 것들이 많다. http://boost.org
  • 38. 8-55. Boo子有親! 부스트를 늘 여러분 가까이에  문자열 및 텍스트 처리  컨테이너  함수 객체 및 고차 프로그래밍  일반화 프로그래밍  템플릿 메타프로그래밍  수학 및 수치 조작  정확성 유지 테스트  자료구조  타 언어 연동 지원  메모리 … 등의 다양한 분야를 지원한다.