SlideShare a Scribd company logo
1 of 19
More Effective C++ 3,4
예외
메모리 누수를 피하는 정공법은 소멸자
함수 수행 도중에 예외를 뱉을 경우 delete가 무시될 수 있다.
수행 부분을 try-catch감싸서 함수 수행이 실패할 경우 delete되도록 할 수 있다.
but 이렇게 하면 delete를 catch문에도 넣어주고 정상 종료 시에도 수행하도록 만들어야 하므로
코드가 중복된다.
따라서 자원 관리 객체 (smart pointer) 등을 사용하여
자원 관리 객체의 소멸자에서 delete를 해주자.
생성자에서는 메모리 누수가 일어나지 않게 하자.
생성되는 도중에 예외가 발생할 경우 그 객체는 소멸자가 불리지 않는다.
(C++은 생성 과정이 완료된 객체만을 안전하게 소멸시키기 때문)
따라서 이 부분에 try-catch를 사용하여 delete하는 부분을 catch에서 처리한 후 해당 생성자를
호출한 상위 객체로 예외를 전파하기 위해 throw를 사용하면 된다.
정상적인 동작을 할 경우도 있으므로 delete하는 부분들을 모아서 cleanUp()등의 함수에 넣은
다음 이를 필요한 곳(catch나 소멸자)에서 사용하는 구조가 바람직하다.
const 포인터를 초기화하는 경우에는 초기화 list에서 바로 new하지 말고 init()함수를 만들어서
그 안에서 try-catch형태로 구현한 후 포인터를 return하는 형태로 만들면 좋다.
소멸자에서는 예외가 탈출하지 못하게 하자.
스택 되감기 동작 중 terminate가 호출되는 것을 막고
소멸자의 동작을 완전히 끝내기 위해서(소멸자가 발생한 예외가 전파되면 소멸자는 실행이 끝나
지 않은 상태로 남게 되므로..)
예외 발생이 매개변수 전달, 가상함수 호출등과는 다른 점은?
예외는 원래 객체의 사본으로 전달 된다. 단 throw는 기존 예외를 중계한다는 뜻으로 예외를 새
로 만들지 않기 때문에 효율적
1. Catch문으로 전달되는 예외는 항상 복사가 기본적으로 한 번씩 일어나게 되어있음
2. catch문으로 넘길 때 암시적 타입변환은 이루어지지 않음.
하지만 상속관계 기반의 타입변환과 , 타입이 있는 포인터에서 타입이 없는 포인터로 바꾸는 경
우는 됨
3. catch문은 등장한 순서대로 사용된다.(가상함수는 그 객체의 동적 타입과 가장 가까운 클래스
에 정의된 함수를 선택하지만 catch는 가장 첫 번째를 선택한다는 것이 다르다.)
발생한 예외는 참조자로 받아내자.
예외 객체를 catch문으로 전달할 때, 값으로 전달하면 값 복사가 2번 일어난다. 발생시에는 파생
클래스 객체였는데 catch문에 들어가면서 기본 클래스로 싹뚝 짤릴 수도 있다.
포인터로 전달하는 경우에는 그냥 던지면 그 포인터가 가르키는 객체가 함수를 벗어나면서 사라
지므로 안된다. 그래서 new exception을 만들어서 던지는 방법이 있는데 exception을 삭제할
것이냐 말 것이냐에 대한 문제가 있다.(exception을 받은 함수에서 이놈이 new로 만들어진 예외
인지 아닌지 모르므로)
결국 남은 것은 참조자로 예외를 받는 것 뿐이다.
예외 처리에 드는 비용에 대해 정확히 파악하자
예외처리를 지원하지 않도록 컴파일하면 컴파일타임과 런타임 모두에서 이득을 볼 수 있다.(프로
그램의 어느 한 부분이라도 예외를 사용하면 다 지원해줘야함..)
try블록을 쓸 경우 추가되는 비용은 5~10% 정도이다.
예외가 발생할 때의 비용은 함수 복귀의 속도와 비교하여 1000배 정도 느리다.
하지만 예외가 발생할 때만 지불하는 비용이므로 없다고 봐도 무방
효율
80 : 20의 법칙
병목현상의 80%는 전체코드의 20%에서 발생한다.
나머지 80%의 코드는 20% 정도밖에 성능에 영향을 주지 않는 것.
지연 평가 방식을 사용하자
최고로 효율적인 코드는 아무 계산도 하지 않는 것. 아무 계산도 하지 않을 수 없다면 계산을 최
대한 뒤로 미룬다면 어떨까? 운이 좋으면 계산을 안하고 넘어갈 수도 있으니까!!
참조 카운팅
string s1 = s2 같이 대상을 복사해서 사용하는 경우를 생각해볼 때, 복사된 대상인 s1이 특별히
값을 저장하거나 하지 않는 이상 실제로 복사하지 않고 참조만 해서 쓰는 것.
데이터 읽기와 쓰기를 구분하기
cout << s1[3] ; 읽기 s[3] = ‘x’; 쓰기
사실 []만으로 쓰기와 읽기를 구별하긴 어렵다. 나중에 배운다고 하니 참아보자
지연 방식의 데이터 가져오기
데이터를 가진 객체를 사용할 때, 통으로 가져오기보다는 필요한 부분만 가져올 수 있도록 인터
페이스를 설계할 것.
지연 방식의 표현식 평가
불필요한 수치계산을 피하는 것. m3 = m1+m2일 때, 나중에 m3를 사용할지 안 할지 모르니까
얘는 그 둘의 합을 저장하는 놈 정도로 기억만 하는 것. ec++에서 초기화는 최대한 늦게할 것 이
라는 항목과 일맥상통하는 느낌!!
예상되는 계산 결과를 미리 준비하면 처리비용은 줄어든다.
많이 사용되는 작업을 미리 해둠으로써 나중에 편하게 가자!!
캐싱(caching)
특정 데이터를 가져올 때(계산할 때), 그 결과를 모아두었다가 데이터를 가져올 때, 모아둔 곳(캐
시)를 먼저 살펴보는 것. 책에서는 std::map에 데이터를 가져올 때마다 저장해두고, 읽어올때는
그 곳을 먼저 뒤져보는 방식으로 썻음
하드에서 데이터를 가져올 때, 뭉탱이로 가져온다.(컴퓨터 아키텍쳐에서 배운 로컬~~근접성 원
리)
배열 같은게 있다고 할 때 그 크기를 늘릴 때마다 new하면 비용이 크니까 미리 크게 늘려놓고 많
이 가져온다.
** new는 힙에서 메모리를 떼어오기 위해 system call을 사용하므로 일반 함수호출보다 비쌈!!
임시 객체의 원류를 이해하자.
임시 객체라는 놈이 있다.
우리가 int temp로 선언하는 그런 변수가 아니다.
예를 들면
D3DXVECTOR3 의 참조자를 매개변수로 받는 함수 A가 있다고 할 때
A( &D3DXVECTOR3(3.0F, 3.0F, 3.0F) )
라고 쓰면 위험하다. 왜냐하면 저 자체로 임시 객체이기 때문에 언제 사라질 지 모르기 때문에!!
(+만드는 데 비용도 든다.)
물론 반환 값이 임시 객체일 때 피할 수 있는 방법은 없지만 생성하는데 비용이 들며
그러므로 언제 생기는 구나 하는 정도는 알아야 한다. 이러한 통찰력을 기르도록 훈련을 하자!!
반환값 최적화
함수를 만들었을 때, 반드시 값으로만 반환할 수 있는 결과도 있다. 이러한 놈들은 반환할 때 임
시 객체를 생성하므로 비용이 든다.
BUT 이러한 놈이라도 임시 객체의 비용이 들지 않게 할 수 있다.
INLINE함수를 통해서!!
이를 반환값 최적화라 한다.
오버로딩은 불필요한 암시적 타입변환을 막는 한 방법이다.
UPINT UPI3, UPI1;
UPI3 = UPI1 + 10;
이 있다고 할 때, UPINT에 OPERATOR overloading된 타입 중 int가 없다면
10을 컴파일러가 암시적 타입변환을 통해서 UPINT형으로 변환한 뒤 계산할 것이다.
UPINT형으로 변환하는 부분에서 임시 객체가 생성되는데 이 또한 비용이므로
UPINT에서 int타입 또한 계산할 수 있도록 operator overloading해둔다면 임시객체는 생성되
지 않는다.
이 때 조심할 것은 lhs든 rhs든 하나는 자기 자신을 타입으로 가져야 한다는 것
UPINT형의 operator를 만드는데 매개변수가 int, int이면 컴파일러는 오류를 뱉는다.
단독 연산자 대신에 =이 붙은 연산자를 사용하는 것이 좋을 때가
대입 형태 연산자(-=, += 같은 거)는 단독 연산자보다 비용이 저렴하다.
왜냐하면 임시 객체를 생성하지 않기 때문,
result = a + b + c + d 로 짜면 임시객체가 여러 개 생성되지만(3개?)
result = a
result += b
result += c
result += d
로 짜면 임시 객체 없이 짤 수 있다.
추가로 책에는 이름 없는 객체를 반환으로 쓰는 것이 좋다고 하나 번역자의 말에 따르면 이름있는
객체나 이름없는 객체나 반환값 최적화가 먹힌다고 하니 큰 상관은 없을 듯 하다.
정 효율이 떨어지면 다른 라이브러리를 사용할 것.
iostream과 stdio는 같은 입출력을 하지만 성능 측면에서 많이 다르다.
printf, scanf 등을 사용한 벤치마크를 돌릴 경우
cout , cin 등을 사용할 때 보다 20% 이상 빠르다.
but 타입 안정성과 확장성은 iostream 함수를 사용할 때 훨씬 좋다.
나에게 맞는 라이브러리를 사용할 수 있는 유연성을 키우자
가상 함수, 다중 상속, 가상 기본 크랠스 RTTI에 들어가는 비용
가상함수 테이블 vtbl
가상 테이블 포인터 vptr
vtbl의 크기는 클래스에 선언된 가상함수의 수에 비례
vtbl이 어디 있냐하면
클래스의 inline도 아니고 순수 가상 함수도 아닌, 함수 중 가장 첫 번째 것의 정의부분(cpp겠지?)
SO, 모든 가상함수가 inline으로 선언되어 있으면 이 규칙을 못 적용하니
모든 obj파일에 그 클래스의 vtbl 사본을 저장하는 사태가 벌어짐 -> 애초에 말이 안됨..(inline
은 컴파일 타임에 꾸겨넣는 것이고 가상함수는 런타임에 결정되니까.. so 가상함수는 inline을 쓸
수 없다!)
가상 함수, 다중 상속, 가상 기본 크랠스 RTTI에 들어가는 비용
class A와 이를 상속받는 B가 있다고 할 때, B객체에 대해 어떤 vtbl을 사용할 것인가? vptr이
알려줌
vptr이 어디 숨겨져 있는지는 컴파일러마다 다름
B b; b->f1() 일 때, f1()이 누구의 것인지 판단하는 절차는
1. b가 가리키는 객체의 vptr을 따라 vtbl로 감
2. vtbl을 뒤져서 f1()의 함수 포인터를 찾아옴
3. 함수 호출
다중 상속을 할 때는 가상 기본 클래스가 따라옴.(상속 계통이 다이아몬드 구조일 때 기본 클래스
를 중복 생성하지 않기 위해..)

More Related Content

What's hot

Effective c++ 정리 chapter 8
Effective c++ 정리 chapter 8Effective c++ 정리 chapter 8
Effective c++ 정리 chapter 8연우 김
 
이펙티브 C++ 스터디
이펙티브 C++ 스터디이펙티브 C++ 스터디
이펙티브 C++ 스터디quxn6
 
연산자 오버로딩
연산자 오버로딩연산자 오버로딩
연산자 오버로딩. Ruvendix
 
More effective c++ chapter1 2_dcshin
More effective c++ chapter1 2_dcshinMore effective c++ chapter1 2_dcshin
More effective c++ chapter1 2_dcshinDong Chan Shin
 
Effective c++ 정리 1~2
Effective c++ 정리 1~2Effective c++ 정리 1~2
Effective c++ 정리 1~2Injae Lee
 
Windows via c++ chapter6
Windows via c++   chapter6Windows via c++   chapter6
Windows via c++ chapter6Shin heemin
 
Effective STL 1~4장 정리
Effective STL 1~4장 정리Effective STL 1~4장 정리
Effective STL 1~4장 정리Shin heemin
 
이펙티브 C++ (7~9)
이펙티브 C++ (7~9)이펙티브 C++ (7~9)
이펙티브 C++ (7~9)익성 조
 
effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리Injae Lee
 
Memory & object pooling
Memory & object poolingMemory & object pooling
Memory & object poolingNam Hyeonuk
 
More effective c++ 항목30부터
More effective c++ 항목30부터More effective c++ 항목30부터
More effective c++ 항목30부터Dong Chan Shin
 
프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기Jongwook Choi
 
More effective c++ 3
More effective c++ 3More effective c++ 3
More effective c++ 3현찬 양
 
Effective c++ 4
Effective c++ 4Effective c++ 4
Effective c++ 4현찬 양
 
C++ Template/STL study
C++ Template/STL studyC++ Template/STL study
C++ Template/STL studySeo Dong-yu
 
모어이펙티브 C++ 5,6
모어이펙티브 C++ 5,6모어이펙티브 C++ 5,6
모어이펙티브 C++ 5,6quxn6
 

What's hot (20)

Effective c++ 정리 chapter 8
Effective c++ 정리 chapter 8Effective c++ 정리 chapter 8
Effective c++ 정리 chapter 8
 
이펙티브 C++ 스터디
이펙티브 C++ 스터디이펙티브 C++ 스터디
이펙티브 C++ 스터디
 
Mec 56
Mec 56Mec 56
Mec 56
 
연산자 오버로딩
연산자 오버로딩연산자 오버로딩
연산자 오버로딩
 
More effective c++ chapter1 2_dcshin
More effective c++ chapter1 2_dcshinMore effective c++ chapter1 2_dcshin
More effective c++ chapter1 2_dcshin
 
Std bind
Std bindStd bind
Std bind
 
MEC++ 3,4
MEC++ 3,4MEC++ 3,4
MEC++ 3,4
 
Effective c++ 정리 1~2
Effective c++ 정리 1~2Effective c++ 정리 1~2
Effective c++ 정리 1~2
 
Windows via c++ chapter6
Windows via c++   chapter6Windows via c++   chapter6
Windows via c++ chapter6
 
Effective STL 1~4장 정리
Effective STL 1~4장 정리Effective STL 1~4장 정리
Effective STL 1~4장 정리
 
Jvm
JvmJvm
Jvm
 
이펙티브 C++ (7~9)
이펙티브 C++ (7~9)이펙티브 C++ (7~9)
이펙티브 C++ (7~9)
 
effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리
 
Memory & object pooling
Memory & object poolingMemory & object pooling
Memory & object pooling
 
More effective c++ 항목30부터
More effective c++ 항목30부터More effective c++ 항목30부터
More effective c++ 항목30부터
 
프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기
 
More effective c++ 3
More effective c++ 3More effective c++ 3
More effective c++ 3
 
Effective c++ 4
Effective c++ 4Effective c++ 4
Effective c++ 4
 
C++ Template/STL study
C++ Template/STL studyC++ Template/STL study
C++ Template/STL study
 
모어이펙티브 C++ 5,6
모어이펙티브 C++ 5,6모어이펙티브 C++ 5,6
모어이펙티브 C++ 5,6
 

Similar to 모어이펙티브 C++ 3,4장 예외, 효율 스터디

More effective c++ chapter3 4
More effective c++ chapter3 4More effective c++ chapter3 4
More effective c++ chapter3 4Dong Chan Shin
 
Effective c++chapter3
Effective c++chapter3Effective c++chapter3
Effective c++chapter3성연 김
 
Effective c++ Chapter1,2
Effective c++ Chapter1,2Effective c++ Chapter1,2
Effective c++ Chapter1,2문익 장
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinDong Chan Shin
 
Tcpl 14장 예외처리
Tcpl 14장 예외처리Tcpl 14장 예외처리
Tcpl 14장 예외처리재정 이
 
More effective c++ chapter4 이후 항목 29까지
More effective c++ chapter4 이후 항목 29까지More effective c++ chapter4 이후 항목 29까지
More effective c++ chapter4 이후 항목 29까지Dong Chan Shin
 
Mec++ chapter3,4
Mec++ chapter3,4Mec++ chapter3,4
Mec++ chapter3,4문익 장
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심흥배 최
 
Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장 Shin heemin
 
Api design for c++ pattern
Api design for c++ patternApi design for c++ pattern
Api design for c++ patternjinho park
 
M3 4 1
M3 4 1M3 4 1
M3 4 1nexthw
 
Api design for c++ ch3 pattern
Api design for c++ ch3 patternApi design for c++ ch3 pattern
Api design for c++ ch3 patternjinho park
 
More effective c++ 챕터3~4ppt
More effective c++ 챕터3~4pptMore effective c++ 챕터3~4ppt
More effective c++ 챕터3~4pptInjae Lee
 
Effective c++chapter1 and2
Effective c++chapter1 and2Effective c++chapter1 and2
Effective c++chapter1 and2성연 김
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)문익 장
 
More effective c++ chapter1,2
More effective c++ chapter1,2More effective c++ chapter1,2
More effective c++ chapter1,2문익 장
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Ryan Park
 
Effective c++chapter4
Effective c++chapter4Effective c++chapter4
Effective c++chapter4성연 김
 
Effective c++ 1,2
Effective c++ 1,2Effective c++ 1,2
Effective c++ 1,2세빈 정
 
이펙티브 C++ 789 공부
이펙티브 C++ 789 공부이펙티브 C++ 789 공부
이펙티브 C++ 789 공부quxn6
 

Similar to 모어이펙티브 C++ 3,4장 예외, 효율 스터디 (20)

More effective c++ chapter3 4
More effective c++ chapter3 4More effective c++ chapter3 4
More effective c++ chapter3 4
 
Effective c++chapter3
Effective c++chapter3Effective c++chapter3
Effective c++chapter3
 
Effective c++ Chapter1,2
Effective c++ Chapter1,2Effective c++ Chapter1,2
Effective c++ Chapter1,2
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshin
 
Tcpl 14장 예외처리
Tcpl 14장 예외처리Tcpl 14장 예외처리
Tcpl 14장 예외처리
 
More effective c++ chapter4 이후 항목 29까지
More effective c++ chapter4 이후 항목 29까지More effective c++ chapter4 이후 항목 29까지
More effective c++ chapter4 이후 항목 29까지
 
Mec++ chapter3,4
Mec++ chapter3,4Mec++ chapter3,4
Mec++ chapter3,4
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심
 
Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장
 
Api design for c++ pattern
Api design for c++ patternApi design for c++ pattern
Api design for c++ pattern
 
M3 4 1
M3 4 1M3 4 1
M3 4 1
 
Api design for c++ ch3 pattern
Api design for c++ ch3 patternApi design for c++ ch3 pattern
Api design for c++ ch3 pattern
 
More effective c++ 챕터3~4ppt
More effective c++ 챕터3~4pptMore effective c++ 챕터3~4ppt
More effective c++ 챕터3~4ppt
 
Effective c++chapter1 and2
Effective c++chapter1 and2Effective c++chapter1 and2
Effective c++chapter1 and2
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)
 
More effective c++ chapter1,2
More effective c++ chapter1,2More effective c++ chapter1,2
More effective c++ chapter1,2
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005
 
Effective c++chapter4
Effective c++chapter4Effective c++chapter4
Effective c++chapter4
 
Effective c++ 1,2
Effective c++ 1,2Effective c++ 1,2
Effective c++ 1,2
 
이펙티브 C++ 789 공부
이펙티브 C++ 789 공부이펙티브 C++ 789 공부
이펙티브 C++ 789 공부
 

More from quxn6

모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디quxn6
 
C++11 Tuple
C++11 TupleC++11 Tuple
C++11 Tuplequxn6
 
비실사렌더링-툰 쉐이딩
비실사렌더링-툰 쉐이딩비실사렌더링-툰 쉐이딩
비실사렌더링-툰 쉐이딩quxn6
 
중급 소켓프로그래밍
중급 소켓프로그래밍중급 소켓프로그래밍
중급 소켓프로그래밍quxn6
 
입체충돌처리
입체충돌처리입체충돌처리
입체충돌처리quxn6
 
introduce unity3D and playmaker basic
introduce unity3D and playmaker basicintroduce unity3D and playmaker basic
introduce unity3D and playmaker basicquxn6
 
TCP echo 서버 및 클라이언트 예제 스터디
TCP echo 서버 및 클라이언트 예제 스터디TCP echo 서버 및 클라이언트 예제 스터디
TCP echo 서버 및 클라이언트 예제 스터디quxn6
 

More from quxn6 (7)

모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디
 
C++11 Tuple
C++11 TupleC++11 Tuple
C++11 Tuple
 
비실사렌더링-툰 쉐이딩
비실사렌더링-툰 쉐이딩비실사렌더링-툰 쉐이딩
비실사렌더링-툰 쉐이딩
 
중급 소켓프로그래밍
중급 소켓프로그래밍중급 소켓프로그래밍
중급 소켓프로그래밍
 
입체충돌처리
입체충돌처리입체충돌처리
입체충돌처리
 
introduce unity3D and playmaker basic
introduce unity3D and playmaker basicintroduce unity3D and playmaker basic
introduce unity3D and playmaker basic
 
TCP echo 서버 및 클라이언트 예제 스터디
TCP echo 서버 및 클라이언트 예제 스터디TCP echo 서버 및 클라이언트 예제 스터디
TCP echo 서버 및 클라이언트 예제 스터디
 

모어이펙티브 C++ 3,4장 예외, 효율 스터디

  • 3. 메모리 누수를 피하는 정공법은 소멸자 함수 수행 도중에 예외를 뱉을 경우 delete가 무시될 수 있다. 수행 부분을 try-catch감싸서 함수 수행이 실패할 경우 delete되도록 할 수 있다. but 이렇게 하면 delete를 catch문에도 넣어주고 정상 종료 시에도 수행하도록 만들어야 하므로 코드가 중복된다. 따라서 자원 관리 객체 (smart pointer) 등을 사용하여 자원 관리 객체의 소멸자에서 delete를 해주자.
  • 4. 생성자에서는 메모리 누수가 일어나지 않게 하자. 생성되는 도중에 예외가 발생할 경우 그 객체는 소멸자가 불리지 않는다. (C++은 생성 과정이 완료된 객체만을 안전하게 소멸시키기 때문) 따라서 이 부분에 try-catch를 사용하여 delete하는 부분을 catch에서 처리한 후 해당 생성자를 호출한 상위 객체로 예외를 전파하기 위해 throw를 사용하면 된다. 정상적인 동작을 할 경우도 있으므로 delete하는 부분들을 모아서 cleanUp()등의 함수에 넣은 다음 이를 필요한 곳(catch나 소멸자)에서 사용하는 구조가 바람직하다. const 포인터를 초기화하는 경우에는 초기화 list에서 바로 new하지 말고 init()함수를 만들어서 그 안에서 try-catch형태로 구현한 후 포인터를 return하는 형태로 만들면 좋다.
  • 5. 소멸자에서는 예외가 탈출하지 못하게 하자. 스택 되감기 동작 중 terminate가 호출되는 것을 막고 소멸자의 동작을 완전히 끝내기 위해서(소멸자가 발생한 예외가 전파되면 소멸자는 실행이 끝나 지 않은 상태로 남게 되므로..)
  • 6. 예외 발생이 매개변수 전달, 가상함수 호출등과는 다른 점은? 예외는 원래 객체의 사본으로 전달 된다. 단 throw는 기존 예외를 중계한다는 뜻으로 예외를 새 로 만들지 않기 때문에 효율적 1. Catch문으로 전달되는 예외는 항상 복사가 기본적으로 한 번씩 일어나게 되어있음 2. catch문으로 넘길 때 암시적 타입변환은 이루어지지 않음. 하지만 상속관계 기반의 타입변환과 , 타입이 있는 포인터에서 타입이 없는 포인터로 바꾸는 경 우는 됨 3. catch문은 등장한 순서대로 사용된다.(가상함수는 그 객체의 동적 타입과 가장 가까운 클래스 에 정의된 함수를 선택하지만 catch는 가장 첫 번째를 선택한다는 것이 다르다.)
  • 7. 발생한 예외는 참조자로 받아내자. 예외 객체를 catch문으로 전달할 때, 값으로 전달하면 값 복사가 2번 일어난다. 발생시에는 파생 클래스 객체였는데 catch문에 들어가면서 기본 클래스로 싹뚝 짤릴 수도 있다. 포인터로 전달하는 경우에는 그냥 던지면 그 포인터가 가르키는 객체가 함수를 벗어나면서 사라 지므로 안된다. 그래서 new exception을 만들어서 던지는 방법이 있는데 exception을 삭제할 것이냐 말 것이냐에 대한 문제가 있다.(exception을 받은 함수에서 이놈이 new로 만들어진 예외 인지 아닌지 모르므로) 결국 남은 것은 참조자로 예외를 받는 것 뿐이다.
  • 8. 예외 처리에 드는 비용에 대해 정확히 파악하자 예외처리를 지원하지 않도록 컴파일하면 컴파일타임과 런타임 모두에서 이득을 볼 수 있다.(프로 그램의 어느 한 부분이라도 예외를 사용하면 다 지원해줘야함..) try블록을 쓸 경우 추가되는 비용은 5~10% 정도이다. 예외가 발생할 때의 비용은 함수 복귀의 속도와 비교하여 1000배 정도 느리다. 하지만 예외가 발생할 때만 지불하는 비용이므로 없다고 봐도 무방
  • 10. 80 : 20의 법칙 병목현상의 80%는 전체코드의 20%에서 발생한다. 나머지 80%의 코드는 20% 정도밖에 성능에 영향을 주지 않는 것.
  • 11. 지연 평가 방식을 사용하자 최고로 효율적인 코드는 아무 계산도 하지 않는 것. 아무 계산도 하지 않을 수 없다면 계산을 최 대한 뒤로 미룬다면 어떨까? 운이 좋으면 계산을 안하고 넘어갈 수도 있으니까!! 참조 카운팅 string s1 = s2 같이 대상을 복사해서 사용하는 경우를 생각해볼 때, 복사된 대상인 s1이 특별히 값을 저장하거나 하지 않는 이상 실제로 복사하지 않고 참조만 해서 쓰는 것. 데이터 읽기와 쓰기를 구분하기 cout << s1[3] ; 읽기 s[3] = ‘x’; 쓰기 사실 []만으로 쓰기와 읽기를 구별하긴 어렵다. 나중에 배운다고 하니 참아보자 지연 방식의 데이터 가져오기 데이터를 가진 객체를 사용할 때, 통으로 가져오기보다는 필요한 부분만 가져올 수 있도록 인터 페이스를 설계할 것. 지연 방식의 표현식 평가 불필요한 수치계산을 피하는 것. m3 = m1+m2일 때, 나중에 m3를 사용할지 안 할지 모르니까 얘는 그 둘의 합을 저장하는 놈 정도로 기억만 하는 것. ec++에서 초기화는 최대한 늦게할 것 이 라는 항목과 일맥상통하는 느낌!!
  • 12. 예상되는 계산 결과를 미리 준비하면 처리비용은 줄어든다. 많이 사용되는 작업을 미리 해둠으로써 나중에 편하게 가자!! 캐싱(caching) 특정 데이터를 가져올 때(계산할 때), 그 결과를 모아두었다가 데이터를 가져올 때, 모아둔 곳(캐 시)를 먼저 살펴보는 것. 책에서는 std::map에 데이터를 가져올 때마다 저장해두고, 읽어올때는 그 곳을 먼저 뒤져보는 방식으로 썻음 하드에서 데이터를 가져올 때, 뭉탱이로 가져온다.(컴퓨터 아키텍쳐에서 배운 로컬~~근접성 원 리) 배열 같은게 있다고 할 때 그 크기를 늘릴 때마다 new하면 비용이 크니까 미리 크게 늘려놓고 많 이 가져온다. ** new는 힙에서 메모리를 떼어오기 위해 system call을 사용하므로 일반 함수호출보다 비쌈!!
  • 13. 임시 객체의 원류를 이해하자. 임시 객체라는 놈이 있다. 우리가 int temp로 선언하는 그런 변수가 아니다. 예를 들면 D3DXVECTOR3 의 참조자를 매개변수로 받는 함수 A가 있다고 할 때 A( &D3DXVECTOR3(3.0F, 3.0F, 3.0F) ) 라고 쓰면 위험하다. 왜냐하면 저 자체로 임시 객체이기 때문에 언제 사라질 지 모르기 때문에!! (+만드는 데 비용도 든다.) 물론 반환 값이 임시 객체일 때 피할 수 있는 방법은 없지만 생성하는데 비용이 들며 그러므로 언제 생기는 구나 하는 정도는 알아야 한다. 이러한 통찰력을 기르도록 훈련을 하자!!
  • 14. 반환값 최적화 함수를 만들었을 때, 반드시 값으로만 반환할 수 있는 결과도 있다. 이러한 놈들은 반환할 때 임 시 객체를 생성하므로 비용이 든다. BUT 이러한 놈이라도 임시 객체의 비용이 들지 않게 할 수 있다. INLINE함수를 통해서!! 이를 반환값 최적화라 한다.
  • 15. 오버로딩은 불필요한 암시적 타입변환을 막는 한 방법이다. UPINT UPI3, UPI1; UPI3 = UPI1 + 10; 이 있다고 할 때, UPINT에 OPERATOR overloading된 타입 중 int가 없다면 10을 컴파일러가 암시적 타입변환을 통해서 UPINT형으로 변환한 뒤 계산할 것이다. UPINT형으로 변환하는 부분에서 임시 객체가 생성되는데 이 또한 비용이므로 UPINT에서 int타입 또한 계산할 수 있도록 operator overloading해둔다면 임시객체는 생성되 지 않는다. 이 때 조심할 것은 lhs든 rhs든 하나는 자기 자신을 타입으로 가져야 한다는 것 UPINT형의 operator를 만드는데 매개변수가 int, int이면 컴파일러는 오류를 뱉는다.
  • 16. 단독 연산자 대신에 =이 붙은 연산자를 사용하는 것이 좋을 때가 대입 형태 연산자(-=, += 같은 거)는 단독 연산자보다 비용이 저렴하다. 왜냐하면 임시 객체를 생성하지 않기 때문, result = a + b + c + d 로 짜면 임시객체가 여러 개 생성되지만(3개?) result = a result += b result += c result += d 로 짜면 임시 객체 없이 짤 수 있다. 추가로 책에는 이름 없는 객체를 반환으로 쓰는 것이 좋다고 하나 번역자의 말에 따르면 이름있는 객체나 이름없는 객체나 반환값 최적화가 먹힌다고 하니 큰 상관은 없을 듯 하다.
  • 17. 정 효율이 떨어지면 다른 라이브러리를 사용할 것. iostream과 stdio는 같은 입출력을 하지만 성능 측면에서 많이 다르다. printf, scanf 등을 사용한 벤치마크를 돌릴 경우 cout , cin 등을 사용할 때 보다 20% 이상 빠르다. but 타입 안정성과 확장성은 iostream 함수를 사용할 때 훨씬 좋다. 나에게 맞는 라이브러리를 사용할 수 있는 유연성을 키우자
  • 18. 가상 함수, 다중 상속, 가상 기본 크랠스 RTTI에 들어가는 비용 가상함수 테이블 vtbl 가상 테이블 포인터 vptr vtbl의 크기는 클래스에 선언된 가상함수의 수에 비례 vtbl이 어디 있냐하면 클래스의 inline도 아니고 순수 가상 함수도 아닌, 함수 중 가장 첫 번째 것의 정의부분(cpp겠지?) SO, 모든 가상함수가 inline으로 선언되어 있으면 이 규칙을 못 적용하니 모든 obj파일에 그 클래스의 vtbl 사본을 저장하는 사태가 벌어짐 -> 애초에 말이 안됨..(inline 은 컴파일 타임에 꾸겨넣는 것이고 가상함수는 런타임에 결정되니까.. so 가상함수는 inline을 쓸 수 없다!)
  • 19. 가상 함수, 다중 상속, 가상 기본 크랠스 RTTI에 들어가는 비용 class A와 이를 상속받는 B가 있다고 할 때, B객체에 대해 어떤 vtbl을 사용할 것인가? vptr이 알려줌 vptr이 어디 숨겨져 있는지는 컴파일러마다 다름 B b; b->f1() 일 때, f1()이 누구의 것인지 판단하는 절차는 1. b가 가리키는 객체의 vptr을 따라 vtbl로 감 2. vtbl을 뒤져서 f1()의 함수 포인터를 찾아옴 3. 함수 호출 다중 상속을 할 때는 가상 기본 클래스가 따라옴.(상속 계통이 다이아몬드 구조일 때 기본 클래스 를 중복 생성하지 않기 위해..)