SlideShare ist ein Scribd-Unternehmen logo
1 von 26
Effective C++_2
131043 양현찬
NHN NEXT
시작하기 전에 결론은
예외기능을 지원하지 않도록 컴파일 하라
리소스 누수방지는 소멸자로
• 지역리소스(스택 할당)를 물고 있는 포인터와 이별하자
• 매번 예외에 delete를 통해 처리해줘야 한다.
• Try-catch문은 코드가 복잡해질 뿐만 아니라 여러 문제를 안고 있
다.
• 소멸자에 delete를 물고 있는 객체인 스마트 포인터를 사용하자
• 윈도우 시스템 API들은 c스타일의 인터페이스를 가지고 있다.
윈도우 시스템 API들의 관리법
• 리소스를 얻어내는 생성자와 해제하는 소멸자를 가진 객체를 이
용하여 c스타일 API들을 관리하자
생성자에서는 누수가 일어나지 않도록
• Operator new는 예외를 발생시킬 위험이 있다.
• C++에서는 생성이 안전하게 완료된 객체에 관해서만 소멸자를
호출한다.
• 이런 점을 염두하고 생성자를 설계해야 한다.
• 스마트 포인터를 사용하면 까다로운 설계문제들을 쉽게 해결할
수 있다.
소멸자에서는 예외가 탈출할 수 없도록
• 소멸자가 호출되는 경우는 두 가지이다.
• 첫째는 통상적인 소멸이다. 즉 지역변수로 생성된 객체가 유효범
위에서 벗어나 소멸되는 경우이다.
• 둘째의 경우는 예외처리 메커니즘에 의해 객체가 소멸될 경우이
다.
• 하지만 소멸자 안에서는 어느 경우에 호출되었는지 알 수 있는
방법이 없다.
소멸자 작성시 예외가 발생한 상태로 가정하자
• 소멸자를 작성할 때 방어적으로 작성해야 한다.
• 예외처리가 진행되고 있는 도중 또 다른 예외 때문에 흐름이 소
멸자 함수를 떠나면 C++에서는 terminate함수를 호출한다.
• Terminate함수 호출 시 칼같이 종료시켜버리기 때문에 지역객체
조차도 소멸되지 않는다.
• 따라서 소멸자 안에서 예외가 발생할 경우 소멸자를 탈출하게 되
는 경우를 만들지 말아야 한다.
예외 발생은 매개변수전달, 가상함수 호출과 다르다.
• 함수의 매개변수 선언과 catch문은 생긴 것도 역할도 비슷하다.
• 함수의 호출은 함수 종료시 흐름이 호출한 부분으로 다시 돌아오
지만 catch문은 throw를 호출한 부분으로 다시 돌아오지 않는
다.(goto문과 비슷하다. 흐림을 깨버린다.)
• 예외를 처리할 때 인자가 Catch by value가 되든 Catch by
reference가 되든 사본생성이 이루어진다. 다만 사본 생성 횟수
가 다르다. Value는 2번 Reference는 1번 생성된다.
• 포인터에 의한 전달은 함수랑 같다.
• 지역객체에 대한 포인터는 넘겨봐야 소용없다. 결국은 유효범위
를 넘어서면 소멸되기 때문이다.
동적 타입과 정적 타입 복사
• 예외를 던질 때는 상수 참조자를 사용할 필요는 없다. 그냥 참조
자를 사용할 수 있다.
• 예외를 전파하는 경우 rethrow를 이용하자. Rethrow는 객체의 복
사가 일어나지 않는다.
• Rethorw란 catch문안에서 throw;를 했을 때를 뜻한다.
예외와 타입변환
• 기본적으로 예외는 암시적인 타입변환이 일어나지 않는다.
• 다만 상속관계의 타입과 포인터로부터 void*로의 타입변환은 허
용된다.
• 예외처리 메커니즘은 „가장 첫째의 것을 선택하는‟ 메커니즘을 따
릅니다.
Try catch문 자동완성을 vs에서 사용하면 이
렇게 기본적으로 3개의 catch문이 생성된다.
아래로 갈수록 부모이다.
발생한 예외는 참조자로
• C++에서 제공하는 표준예외는 전부 포인터가 아니다.
• Catch by pointer는 좋은 방법이 아니다.
• 전역변수나 힙에 할당된 경우에만 유용할 뿐더러 관리도 힘들고
delete여부도 알기 힘들다.
• Catch by value는 2번 사본이 생성될 뿐만 아니라 slicing
problem을 가지고 있다.
• Slicing problem은 부모의 객체영역만 복사되어 자식의 영역이
잘려나가는 현상이다.
예외지정기능은 냉철하게
• 함수가 발생시킬 예외를 미리 생성할 때 지정하는 것을 예외지정
이라고 한다.
• 예외지정에 일관성이 없을 경우 컴파일 도중 발견해주고 함수가
예외지정 리스트에 없는 예외를 발생시킬 경우 런타임 에러와 함
께 unexpected라는 특수 함수가 자동으로 호출된다.
• 문제는 unexpected함수가 terminate를 호출하는데 이에 대해서
는 알고 있듯 그냥 프로그램이 멈추어 버린다.
• Unexpected함수는 매우 쉽게 호출될 수 있는 함수이기 때문에
예외지정은 신중하게 사용해야 한다.
Unexpected함수의 나락을 막는 법
• 예외 지정된 새로운 코드와 예외지정이 안된 옛날 코드가 섞일
수 있기 때문에 조심하자
• 예외지정이 안 된 함수를 호출할 가능성을 가진 함수에는 예외
지정을 두지 않는다.
• 템플릿과 예외지정은 어울리지 않는다 사용하지 말자
• “시스템”이 일으킬 가능성이 있는 예외(C++표준 예외)를 처리하
자
• 아래와 같은 명령을 통해 unexpected함수를 대체할 사용자의 함
수를 만든다.
예외처리에 드는 비용
• 예외처리를 검사하기 위해서 들어가는 내부적인 비용은 존재한
다.
• 예외기능이 들어가지 않는 라이브러리를 제작하기로 결정했다면
예외기능 없이 컴파일 하는 것이 코드 최적화에 상당한 기능을
준다.
• Try블록으로 인해 생기는 비용이 있다. 쓸데없이 try블록을 남발
해서는 안 된다.
• 우선 가능하다면 예외기능을 지원하지 않도록 컴파일 하라.
80 - 20
• 프로그램 리소스의 80%는 전체 실행 코드의 20%만이 사용한다.
• 실행의 핵심을 담당하는 코드 20%를 이해하고 이 부분을 효율적
으로 만들어야 한다.
• 대부분의 프로그래머들은 자신이 짠 코드가 어느 정도의 수행 성
능을 가지고 있는지 파악하지 못하고 있다.
• 프로파일러를 사용하여 20%부분을 찾아내자
• 20%를 뚫어보는 능력이 필요하다.
지연평가는 충분히 고려할 만하다
• 작업 결과가 진짜로 필요해질 때까지 그 처리를 미룬다. 예를 들
어 게임 프레임 60이하로 떨어지기 전까지는 고려하지 않아도 된
다.
• 진짜 필요해지기 전까지는 자기만의 데이터 사본을 만들지 않고
남의 것을 끌어다 사용한다
• „지연된 데이터 가져오기‟ 해당하는 데이터가 진짜로 필요할 경우
에만 가져오는 기법이다. 그 전까지는 메모리에는 객체의 껍데기
만 있다.
• 결과가 같은 동작을 여러 번 해야 할 경우 미리 그 결과를 저장해
놓고 사용한다.
예상되는 결과를 미리 준비하자
• 미리 준비하면 처리 비용을 절약할 수 있다.
• 상당히 자주 요구될 것 같은 계산이 있다면, 그 요구를 효율적으
로 처리할 수 있는 자료구조를 설계하여 비용을 낮추자.
• STL사용시 iter->second가 아닌 *(iter).second 이런 형태로
iterator를 사용하자
• CPU의 연산을 메모리로 돌릴 수 있다. 즉 메모리를 쓸 수록 속도
가 빨라진다.
임시 객체의 근원을 정확히 이해하자
• 임시 객체란 우리코드에 보이지 않는 임시로 만들어진 „이름 없
는‟ 객체이다.
• 함수호출을 성사시키기 위한 암시적 타입변환이 적용 될 때 생성
된다.
• Return by value를 할 때 생성된다.
• 암시적 타입 변환이 일어나는 경우는 오직 객체가 값으로 전달
될 경우와 reference to const(상수 참조자)가 전달될 경우이다.
• 객체를 value로 반환하는 대부분의 함수는 반환 시 임시객체를
피할 수 없다. 컴파일러의 최적화만 믿을 뿐이다.
반환 값 최적화가 가능하도록 하자
• 지역 변수의 값을 참조자로 반환하거나 포인터로 반환하는 일은
하지 말자.
• 컴파일러가 최적화 가능한 형태로 코드를 작성하자.
오버로딩은 불필요한 암시적 타입변환을 막는다.
• 암시적 타입변환은 정말 편리하지만 임시객체의 생성은 우리가
원하지 않는다.
• 함수의 오버로딩을 통해 다양한 경우에 대해 준비함으로써 암시
적 타입변환을 막을 수 있다.
• 오버로딩 되는 연산자 함수는 반드시 최소한 한 개 이상의 사용
자타입이 인자로 들어가야 한다.
• 물론 프로그램의 효율은 고려하자 사용하지도 않는 함수를 쌓아
놓지 말자.
+보다 +=을 사용할 수 있으면 하자
• 연산자를 만들어서 사용할 때 대입 연산자를 통해 단독 연산자를
작성하면 자연스럽게 두 연산자를 관계 지어 둘 수 있다.
• 대입 연산자는 임시객체를 만들지 않기 때문에 효율적이다.
• 대입 연산자는 매우 편리하다.
• 대입 연산자를 통해 단독 연산자를 작성할 때 이름없는 형태의
임시객체를 만들어 반환 할 수 있기 때문에 임시객체 최적화를
컴파일러에게 부탁할 수 있다.(슬라이드 19장 참고)
정 안 되면 다른 라이브러리 쓰자
• 사용하는 라이브러리에서 병목현상이 발견된다면 그냥 라이브러
리를 바꿔라. 비슷한 걸로.
• 라이브러리만 바꿔도 눈에 띄게 수행성능이 달라질 수 있다.
• Stdio가 iostream보다 지금은 빠르지만 iostream이 stdio보다 빨
라질 수 있는 날이 올 수도 있다.
• 아마 그땐 내가 은퇴했을지도(….)
가상함수, 다중상속, 가상 기본 클래스, RTTI 의 비용
• 가상함수가 생성될 때 가상 테이블(vtbl)과 가상 테이블 포인터
(vptr)가 함께 생성된다.
• Vtbl은 함수포인터의 배열이며 가상함수의 선언 뿐만 아니라 상
속받은 클래스에도 생성된다. 그리고 가상함수의 시작주소(함수
포인터)를 물고있다.
• 컴파일러가 필요한 목적파일마다 vtbl을 생성하고 링커가 중복을
제거해주거나 heuristic이라는 규칙을 사용해서 vtbl을 가질 목적
파일을 결정해준다.
• Inline도 아니고 순수가상 함수도 아닌 함수 중 첫 번째 정의부분
에 vtbl을 넣기로 하는 규칙이다.
• Heuristic규칙은 가상함수를 inline으로 너무 많이 선언할 때 적용
할 수 없게 된다.
가상 함수
• Virtual의 의미는 “호출 할 함수를 런타임까지 기다려서 결정한다.”
이다.
• Vptr은 „어떤 객체에 대해 어떤 vtbl을 사용할 것인가‟를 결정한다.
• 해당하는 클래스의 숨겨진 데이터 멤버 변수형태로 선언된다.
• 가상함수만 놓고 수행성능의 발목을 잡는다고 보기는 힘들다. 고
작 명령어 몇 개가 더 실행되는 수준이다.
• 가상함수는 inline을 포기해야 한다. (참조자나 포인터를 사용할
경우에만 해당되지만 일반적으로 참조자나 포인터만 사용한다.)
가상 기본 클래스
• 이것이 없으면 하나의 파생클래스에서 기본클래스까지의 길이
두 가지일 때 기본클래스가 중복되는 현상이 발생하기 때문에 필
요하다.
• 잘 생각하고 사용해야 한다. 각각에 대해서 vptr과 vtbl이 생성되
기 때문이다.
RTTI 런타임 타입 식별
• RTTI는 실행 중에 객체와 클래스의 정보를 알아낼 수 있지만 이
정보를 저장할 메모리가 당연히 필요하다.
• 이 정보는 type_info라는 객체에 저장되며, typeid연산자를 사용
해서 액세스할 수 있다.
• RTTL은 vtbl을 통해서만 구현될 수 있도록 설계되었기 때문에 해
당 클래스에 가상함수가 하나는 꼭 들어있어야 한다.

Weitere ähnliche Inhalte

Was ist angesagt?

effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리Injae Lee
 
이펙티브 C++ 공부
이펙티브 C++ 공부이펙티브 C++ 공부
이펙티브 C++ 공부quxn6
 
Effective c++ 정리 1~2
Effective c++ 정리 1~2Effective c++ 정리 1~2
Effective c++ 정리 1~2Injae Lee
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Nam Hyeonuk
 
Effective c++ 1,2
Effective c++ 1,2Effective c++ 1,2
Effective c++ 1,2세빈 정
 
이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디quxn6
 
이펙티브 C++ 스터디
이펙티브 C++ 스터디이펙티브 C++ 스터디
이펙티브 C++ 스터디quxn6
 
Effective C++ Chaper 1
Effective C++ Chaper 1Effective C++ Chaper 1
Effective C++ Chaper 1연우 김
 
이펙티브 C++ (7~9)
이펙티브 C++ (7~9)이펙티브 C++ (7~9)
이펙티브 C++ (7~9)익성 조
 
모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디quxn6
 
Effective c++ 챕터 2 정리
Effective c++ 챕터 2 정리Effective c++ 챕터 2 정리
Effective c++ 챕터 2 정리연우 김
 
M1 2 1
M1 2 1M1 2 1
M1 2 1nexthw
 
Effective c++ 정리 chapter 6
Effective c++ 정리 chapter 6Effective c++ 정리 chapter 6
Effective c++ 정리 chapter 6연우 김
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinDong Chan Shin
 
Effective C++ Chapter 1 Summary
Effective C++ Chapter 1 SummaryEffective C++ Chapter 1 Summary
Effective C++ Chapter 1 SummarySeungYeonChoi10
 
Effective c++chapter3
Effective c++chapter3Effective c++chapter3
Effective c++chapter3성연 김
 
More effective c++ 3주차
More effective c++ 3주차More effective c++ 3주차
More effective c++ 3주차Injae Lee
 
Effective c++ 정리 chapter 4
Effective c++ 정리 chapter 4Effective c++ 정리 chapter 4
Effective c++ 정리 chapter 4연우 김
 
Effective C++ 정리 chapter 3
Effective C++ 정리 chapter 3Effective C++ 정리 chapter 3
Effective C++ 정리 chapter 3연우 김
 

Was ist angesagt? (20)

5 6 1
5 6 15 6 1
5 6 1
 
effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리
 
이펙티브 C++ 공부
이펙티브 C++ 공부이펙티브 C++ 공부
이펙티브 C++ 공부
 
Effective c++ 정리 1~2
Effective c++ 정리 1~2Effective c++ 정리 1~2
Effective c++ 정리 1~2
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약
 
Effective c++ 1,2
Effective c++ 1,2Effective c++ 1,2
Effective c++ 1,2
 
이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디
 
이펙티브 C++ 스터디
이펙티브 C++ 스터디이펙티브 C++ 스터디
이펙티브 C++ 스터디
 
Effective C++ Chaper 1
Effective C++ Chaper 1Effective C++ Chaper 1
Effective C++ Chaper 1
 
이펙티브 C++ (7~9)
이펙티브 C++ (7~9)이펙티브 C++ (7~9)
이펙티브 C++ (7~9)
 
모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디
 
Effective c++ 챕터 2 정리
Effective c++ 챕터 2 정리Effective c++ 챕터 2 정리
Effective c++ 챕터 2 정리
 
M1 2 1
M1 2 1M1 2 1
M1 2 1
 
Effective c++ 정리 chapter 6
Effective c++ 정리 chapter 6Effective c++ 정리 chapter 6
Effective c++ 정리 chapter 6
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshin
 
Effective C++ Chapter 1 Summary
Effective C++ Chapter 1 SummaryEffective C++ Chapter 1 Summary
Effective C++ Chapter 1 Summary
 
Effective c++chapter3
Effective c++chapter3Effective c++chapter3
Effective c++chapter3
 
More effective c++ 3주차
More effective c++ 3주차More effective c++ 3주차
More effective c++ 3주차
 
Effective c++ 정리 chapter 4
Effective c++ 정리 chapter 4Effective c++ 정리 chapter 4
Effective c++ 정리 chapter 4
 
Effective C++ 정리 chapter 3
Effective C++ 정리 chapter 3Effective C++ 정리 chapter 3
Effective C++ 정리 chapter 3
 

Andere mochten auch

초등학생도 하는 그냥 DB설치
초등학생도 하는 그냥 DB설치초등학생도 하는 그냥 DB설치
초등학생도 하는 그냥 DB설치현찬 양
 
Open gl 시작하기
Open gl 시작하기Open gl 시작하기
Open gl 시작하기현찬 양
 
Effective c++ 3
Effective c++ 3Effective c++ 3
Effective c++ 3현찬 양
 
실전프로젝트 정서경 양현찬
실전프로젝트 정서경 양현찬실전프로젝트 정서경 양현찬
실전프로젝트 정서경 양현찬현찬 양
 

Andere mochten auch (6)

초등학생도 하는 그냥 DB설치
초등학생도 하는 그냥 DB설치초등학생도 하는 그냥 DB설치
초등학생도 하는 그냥 DB설치
 
Open gl 시작하기
Open gl 시작하기Open gl 시작하기
Open gl 시작하기
 
Mesh slice 1
Mesh slice 1Mesh slice 1
Mesh slice 1
 
쿼터니언
쿼터니언쿼터니언
쿼터니언
 
Effective c++ 3
Effective c++ 3Effective c++ 3
Effective c++ 3
 
실전프로젝트 정서경 양현찬
실전프로젝트 정서경 양현찬실전프로젝트 정서경 양현찬
실전프로젝트 정서경 양현찬
 

Ähnlich wie More effective c++ 2

Mec++ chapter3,4
Mec++ chapter3,4Mec++ chapter3,4
Mec++ chapter3,4문익 장
 
More effective c++ 챕터3~4ppt
More effective c++ 챕터3~4pptMore effective c++ 챕터3~4ppt
More effective c++ 챕터3~4pptInjae Lee
 
Effective c++ chapter 7,8
Effective c++ chapter 7,8Effective c++ chapter 7,8
Effective c++ chapter 7,8문익 장
 
연산자 오버로딩
연산자 오버로딩연산자 오버로딩
연산자 오버로딩수빈 박
 
More effective c++ chapter1,2
More effective c++ chapter1,2More effective c++ chapter1,2
More effective c++ chapter1,2문익 장
 
Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장 Shin heemin
 
M3 4 1
M3 4 1M3 4 1
M3 4 1nexthw
 
Effective java
Effective javaEffective java
Effective javaHaeil Yi
 
Chapter7~9 ppt
Chapter7~9 pptChapter7~9 ppt
Chapter7~9 pptInjae Lee
 
Ec++ 3,4 summary
Ec++ 3,4 summaryEc++ 3,4 summary
Ec++ 3,4 summarySehyeon Nam
 
Effective STL 1~4장 정리
Effective STL 1~4장 정리Effective STL 1~4장 정리
Effective STL 1~4장 정리Shin heemin
 
C++ Advanced 강의 4주차
 C++ Advanced 강의 4주차 C++ Advanced 강의 4주차
C++ Advanced 강의 4주차HyunJoon Park
 
Effective c++ Chapter1,2
Effective c++ Chapter1,2Effective c++ Chapter1,2
Effective c++ Chapter1,2문익 장
 
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
 
More Effective C++ 4주차
More Effective C++ 4주차More Effective C++ 4주차
More Effective C++ 4주차Injae Lee
 
Microsoft pp lpdf
Microsoft pp lpdfMicrosoft pp lpdf
Microsoft pp lpdfHYUNWOO KIM
 
2013 C++ Study For Students #1
2013 C++ Study For Students #12013 C++ Study For Students #1
2013 C++ Study For Students #1Chris Ohk
 
Chapter5 ~ 6
Chapter5 ~ 6Chapter5 ~ 6
Chapter5 ~ 6Injae Lee
 

Ähnlich wie More effective c++ 2 (20)

Mec++ chapter3,4
Mec++ chapter3,4Mec++ chapter3,4
Mec++ chapter3,4
 
MEC++ 3,4
MEC++ 3,4MEC++ 3,4
MEC++ 3,4
 
More effective c++ 챕터3~4ppt
More effective c++ 챕터3~4pptMore effective c++ 챕터3~4ppt
More effective c++ 챕터3~4ppt
 
Effective c++ chapter 7,8
Effective c++ chapter 7,8Effective c++ chapter 7,8
Effective c++ chapter 7,8
 
연산자 오버로딩
연산자 오버로딩연산자 오버로딩
연산자 오버로딩
 
More effective c++ chapter1,2
More effective c++ chapter1,2More effective c++ chapter1,2
More effective c++ chapter1,2
 
Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장
 
M3 4 1
M3 4 1M3 4 1
M3 4 1
 
Effective java
Effective javaEffective java
Effective java
 
Chapter7~9 ppt
Chapter7~9 pptChapter7~9 ppt
Chapter7~9 ppt
 
Ec++ 3,4 summary
Ec++ 3,4 summaryEc++ 3,4 summary
Ec++ 3,4 summary
 
Effective STL 1~4장 정리
Effective STL 1~4장 정리Effective STL 1~4장 정리
Effective STL 1~4장 정리
 
C++ Advanced 강의 4주차
 C++ Advanced 강의 4주차 C++ Advanced 강의 4주차
C++ Advanced 강의 4주차
 
Effective c++ Chapter1,2
Effective c++ Chapter1,2Effective c++ Chapter1,2
Effective c++ Chapter1,2
 
1 2 1
1 2 11 2 1
1 2 1
 
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++
 
More Effective C++ 4주차
More Effective C++ 4주차More Effective C++ 4주차
More Effective C++ 4주차
 
Microsoft pp lpdf
Microsoft pp lpdfMicrosoft pp lpdf
Microsoft pp lpdf
 
2013 C++ Study For Students #1
2013 C++ Study For Students #12013 C++ Study For Students #1
2013 C++ Study For Students #1
 
Chapter5 ~ 6
Chapter5 ~ 6Chapter5 ~ 6
Chapter5 ~ 6
 

More effective c++ 2

  • 2. 시작하기 전에 결론은 예외기능을 지원하지 않도록 컴파일 하라
  • 3. 리소스 누수방지는 소멸자로 • 지역리소스(스택 할당)를 물고 있는 포인터와 이별하자 • 매번 예외에 delete를 통해 처리해줘야 한다. • Try-catch문은 코드가 복잡해질 뿐만 아니라 여러 문제를 안고 있 다. • 소멸자에 delete를 물고 있는 객체인 스마트 포인터를 사용하자 • 윈도우 시스템 API들은 c스타일의 인터페이스를 가지고 있다.
  • 4. 윈도우 시스템 API들의 관리법 • 리소스를 얻어내는 생성자와 해제하는 소멸자를 가진 객체를 이 용하여 c스타일 API들을 관리하자
  • 5. 생성자에서는 누수가 일어나지 않도록 • Operator new는 예외를 발생시킬 위험이 있다. • C++에서는 생성이 안전하게 완료된 객체에 관해서만 소멸자를 호출한다. • 이런 점을 염두하고 생성자를 설계해야 한다. • 스마트 포인터를 사용하면 까다로운 설계문제들을 쉽게 해결할 수 있다.
  • 6. 소멸자에서는 예외가 탈출할 수 없도록 • 소멸자가 호출되는 경우는 두 가지이다. • 첫째는 통상적인 소멸이다. 즉 지역변수로 생성된 객체가 유효범 위에서 벗어나 소멸되는 경우이다. • 둘째의 경우는 예외처리 메커니즘에 의해 객체가 소멸될 경우이 다. • 하지만 소멸자 안에서는 어느 경우에 호출되었는지 알 수 있는 방법이 없다.
  • 7. 소멸자 작성시 예외가 발생한 상태로 가정하자 • 소멸자를 작성할 때 방어적으로 작성해야 한다. • 예외처리가 진행되고 있는 도중 또 다른 예외 때문에 흐름이 소 멸자 함수를 떠나면 C++에서는 terminate함수를 호출한다. • Terminate함수 호출 시 칼같이 종료시켜버리기 때문에 지역객체 조차도 소멸되지 않는다. • 따라서 소멸자 안에서 예외가 발생할 경우 소멸자를 탈출하게 되 는 경우를 만들지 말아야 한다.
  • 8. 예외 발생은 매개변수전달, 가상함수 호출과 다르다. • 함수의 매개변수 선언과 catch문은 생긴 것도 역할도 비슷하다. • 함수의 호출은 함수 종료시 흐름이 호출한 부분으로 다시 돌아오 지만 catch문은 throw를 호출한 부분으로 다시 돌아오지 않는 다.(goto문과 비슷하다. 흐림을 깨버린다.) • 예외를 처리할 때 인자가 Catch by value가 되든 Catch by reference가 되든 사본생성이 이루어진다. 다만 사본 생성 횟수 가 다르다. Value는 2번 Reference는 1번 생성된다. • 포인터에 의한 전달은 함수랑 같다. • 지역객체에 대한 포인터는 넘겨봐야 소용없다. 결국은 유효범위 를 넘어서면 소멸되기 때문이다.
  • 9. 동적 타입과 정적 타입 복사 • 예외를 던질 때는 상수 참조자를 사용할 필요는 없다. 그냥 참조 자를 사용할 수 있다. • 예외를 전파하는 경우 rethrow를 이용하자. Rethrow는 객체의 복 사가 일어나지 않는다. • Rethorw란 catch문안에서 throw;를 했을 때를 뜻한다.
  • 10. 예외와 타입변환 • 기본적으로 예외는 암시적인 타입변환이 일어나지 않는다. • 다만 상속관계의 타입과 포인터로부터 void*로의 타입변환은 허 용된다. • 예외처리 메커니즘은 „가장 첫째의 것을 선택하는‟ 메커니즘을 따 릅니다. Try catch문 자동완성을 vs에서 사용하면 이 렇게 기본적으로 3개의 catch문이 생성된다. 아래로 갈수록 부모이다.
  • 11. 발생한 예외는 참조자로 • C++에서 제공하는 표준예외는 전부 포인터가 아니다. • Catch by pointer는 좋은 방법이 아니다. • 전역변수나 힙에 할당된 경우에만 유용할 뿐더러 관리도 힘들고 delete여부도 알기 힘들다. • Catch by value는 2번 사본이 생성될 뿐만 아니라 slicing problem을 가지고 있다. • Slicing problem은 부모의 객체영역만 복사되어 자식의 영역이 잘려나가는 현상이다.
  • 12. 예외지정기능은 냉철하게 • 함수가 발생시킬 예외를 미리 생성할 때 지정하는 것을 예외지정 이라고 한다. • 예외지정에 일관성이 없을 경우 컴파일 도중 발견해주고 함수가 예외지정 리스트에 없는 예외를 발생시킬 경우 런타임 에러와 함 께 unexpected라는 특수 함수가 자동으로 호출된다. • 문제는 unexpected함수가 terminate를 호출하는데 이에 대해서 는 알고 있듯 그냥 프로그램이 멈추어 버린다. • Unexpected함수는 매우 쉽게 호출될 수 있는 함수이기 때문에 예외지정은 신중하게 사용해야 한다.
  • 13. Unexpected함수의 나락을 막는 법 • 예외 지정된 새로운 코드와 예외지정이 안된 옛날 코드가 섞일 수 있기 때문에 조심하자 • 예외지정이 안 된 함수를 호출할 가능성을 가진 함수에는 예외 지정을 두지 않는다. • 템플릿과 예외지정은 어울리지 않는다 사용하지 말자 • “시스템”이 일으킬 가능성이 있는 예외(C++표준 예외)를 처리하 자 • 아래와 같은 명령을 통해 unexpected함수를 대체할 사용자의 함 수를 만든다.
  • 14. 예외처리에 드는 비용 • 예외처리를 검사하기 위해서 들어가는 내부적인 비용은 존재한 다. • 예외기능이 들어가지 않는 라이브러리를 제작하기로 결정했다면 예외기능 없이 컴파일 하는 것이 코드 최적화에 상당한 기능을 준다. • Try블록으로 인해 생기는 비용이 있다. 쓸데없이 try블록을 남발 해서는 안 된다. • 우선 가능하다면 예외기능을 지원하지 않도록 컴파일 하라.
  • 15. 80 - 20 • 프로그램 리소스의 80%는 전체 실행 코드의 20%만이 사용한다. • 실행의 핵심을 담당하는 코드 20%를 이해하고 이 부분을 효율적 으로 만들어야 한다. • 대부분의 프로그래머들은 자신이 짠 코드가 어느 정도의 수행 성 능을 가지고 있는지 파악하지 못하고 있다. • 프로파일러를 사용하여 20%부분을 찾아내자 • 20%를 뚫어보는 능력이 필요하다.
  • 16. 지연평가는 충분히 고려할 만하다 • 작업 결과가 진짜로 필요해질 때까지 그 처리를 미룬다. 예를 들 어 게임 프레임 60이하로 떨어지기 전까지는 고려하지 않아도 된 다. • 진짜 필요해지기 전까지는 자기만의 데이터 사본을 만들지 않고 남의 것을 끌어다 사용한다 • „지연된 데이터 가져오기‟ 해당하는 데이터가 진짜로 필요할 경우 에만 가져오는 기법이다. 그 전까지는 메모리에는 객체의 껍데기 만 있다. • 결과가 같은 동작을 여러 번 해야 할 경우 미리 그 결과를 저장해 놓고 사용한다.
  • 17. 예상되는 결과를 미리 준비하자 • 미리 준비하면 처리 비용을 절약할 수 있다. • 상당히 자주 요구될 것 같은 계산이 있다면, 그 요구를 효율적으 로 처리할 수 있는 자료구조를 설계하여 비용을 낮추자. • STL사용시 iter->second가 아닌 *(iter).second 이런 형태로 iterator를 사용하자 • CPU의 연산을 메모리로 돌릴 수 있다. 즉 메모리를 쓸 수록 속도 가 빨라진다.
  • 18. 임시 객체의 근원을 정확히 이해하자 • 임시 객체란 우리코드에 보이지 않는 임시로 만들어진 „이름 없 는‟ 객체이다. • 함수호출을 성사시키기 위한 암시적 타입변환이 적용 될 때 생성 된다. • Return by value를 할 때 생성된다. • 암시적 타입 변환이 일어나는 경우는 오직 객체가 값으로 전달 될 경우와 reference to const(상수 참조자)가 전달될 경우이다. • 객체를 value로 반환하는 대부분의 함수는 반환 시 임시객체를 피할 수 없다. 컴파일러의 최적화만 믿을 뿐이다.
  • 19. 반환 값 최적화가 가능하도록 하자 • 지역 변수의 값을 참조자로 반환하거나 포인터로 반환하는 일은 하지 말자. • 컴파일러가 최적화 가능한 형태로 코드를 작성하자.
  • 20. 오버로딩은 불필요한 암시적 타입변환을 막는다. • 암시적 타입변환은 정말 편리하지만 임시객체의 생성은 우리가 원하지 않는다. • 함수의 오버로딩을 통해 다양한 경우에 대해 준비함으로써 암시 적 타입변환을 막을 수 있다. • 오버로딩 되는 연산자 함수는 반드시 최소한 한 개 이상의 사용 자타입이 인자로 들어가야 한다. • 물론 프로그램의 효율은 고려하자 사용하지도 않는 함수를 쌓아 놓지 말자.
  • 21. +보다 +=을 사용할 수 있으면 하자 • 연산자를 만들어서 사용할 때 대입 연산자를 통해 단독 연산자를 작성하면 자연스럽게 두 연산자를 관계 지어 둘 수 있다. • 대입 연산자는 임시객체를 만들지 않기 때문에 효율적이다. • 대입 연산자는 매우 편리하다. • 대입 연산자를 통해 단독 연산자를 작성할 때 이름없는 형태의 임시객체를 만들어 반환 할 수 있기 때문에 임시객체 최적화를 컴파일러에게 부탁할 수 있다.(슬라이드 19장 참고)
  • 22. 정 안 되면 다른 라이브러리 쓰자 • 사용하는 라이브러리에서 병목현상이 발견된다면 그냥 라이브러 리를 바꿔라. 비슷한 걸로. • 라이브러리만 바꿔도 눈에 띄게 수행성능이 달라질 수 있다. • Stdio가 iostream보다 지금은 빠르지만 iostream이 stdio보다 빨 라질 수 있는 날이 올 수도 있다. • 아마 그땐 내가 은퇴했을지도(….)
  • 23. 가상함수, 다중상속, 가상 기본 클래스, RTTI 의 비용 • 가상함수가 생성될 때 가상 테이블(vtbl)과 가상 테이블 포인터 (vptr)가 함께 생성된다. • Vtbl은 함수포인터의 배열이며 가상함수의 선언 뿐만 아니라 상 속받은 클래스에도 생성된다. 그리고 가상함수의 시작주소(함수 포인터)를 물고있다. • 컴파일러가 필요한 목적파일마다 vtbl을 생성하고 링커가 중복을 제거해주거나 heuristic이라는 규칙을 사용해서 vtbl을 가질 목적 파일을 결정해준다. • Inline도 아니고 순수가상 함수도 아닌 함수 중 첫 번째 정의부분 에 vtbl을 넣기로 하는 규칙이다. • Heuristic규칙은 가상함수를 inline으로 너무 많이 선언할 때 적용 할 수 없게 된다.
  • 24. 가상 함수 • Virtual의 의미는 “호출 할 함수를 런타임까지 기다려서 결정한다.” 이다. • Vptr은 „어떤 객체에 대해 어떤 vtbl을 사용할 것인가‟를 결정한다. • 해당하는 클래스의 숨겨진 데이터 멤버 변수형태로 선언된다. • 가상함수만 놓고 수행성능의 발목을 잡는다고 보기는 힘들다. 고 작 명령어 몇 개가 더 실행되는 수준이다. • 가상함수는 inline을 포기해야 한다. (참조자나 포인터를 사용할 경우에만 해당되지만 일반적으로 참조자나 포인터만 사용한다.)
  • 25. 가상 기본 클래스 • 이것이 없으면 하나의 파생클래스에서 기본클래스까지의 길이 두 가지일 때 기본클래스가 중복되는 현상이 발생하기 때문에 필 요하다. • 잘 생각하고 사용해야 한다. 각각에 대해서 vptr과 vtbl이 생성되 기 때문이다.
  • 26. RTTI 런타임 타입 식별 • RTTI는 실행 중에 객체와 클래스의 정보를 알아낼 수 있지만 이 정보를 저장할 메모리가 당연히 필요하다. • 이 정보는 type_info라는 객체에 저장되며, typeid연산자를 사용 해서 액세스할 수 있다. • RTTL은 vtbl을 통해서만 구현될 수 있도록 설계되었기 때문에 해 당 클래스에 가상함수가 하나는 꼭 들어있어야 한다.