SlideShare a Scribd company logo
1 of 57
DevRookie
Effective C++
Review
2021.06.05
By TonyChoiMS
C++를 언어들의 연합체로 바라보는 안목은 필수
#define을 쓰려거든 const, enum, inline을 떠올리자
낌새만 보이면 const를 들이대보자!
객체를 사용하기 전에 반드시 그 객체를 초기화 하자!
C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세
우자
Index
01
02
03
04
05
C++에 왔으면 C++의 법을 따릅시다
C++는 다중패러다임 프로그래밍 언어로 불립니다.
- 절차적(Procedural) 프로그래밍을 기본으로 하여
- 객체 지향 (object – oriented)
- 함수식 (functional)
- 일반화 (Generic)
- 메타프로그래밍 (metaProgramming)
C++를 언어들의 연합체로 바라보는 안목은 필수
01
4
C++는 한가지 프로그래밍 규칙 아래 있는 통합 언어가 아니라, 4개의
하위언어(Sub Language)를 제공하는 연합체로 구성되어 있습니다.
- C : C++는 C를 기본으로 하고 있습니다.
- 객체 지향 : 클래스, 캡슐화, 다형성, 가상 함수(동적 바인딩)
- 템플릿 C++ : 일반화 프로그래밍, 템플릿 메타 프로그래밍 (TMP)
- STL : 템플릿 라이브러리, 컨테이너, 반복자, 알고리즘, 함수 객체
C++를 언어들의 연합체로 바라보는 안목은 필수
01
5
#define을 쓰려거든 const, enum,
inline을 떠올리자
가급적 선행 처리자보다 컴파일러를 더 가까이 하자.
1. #define ASPECT_RATIO 1.653
- define을 사용할 경우 사용자에겐 기호식 이름으로 보이지만,
컴파일 러는 선행 처리자가 숫자 상수로 바꾸기 때문에
ASPECT_RATIO라는 이름은 컴파일러가 쓰는 기호 테이블에 들어
가지 않게 됩니다.
- 에러가 발생하게 될 경우 에러 메시지가 ASPECT_RATIO가 아
#define을 쓰려거든 const, enum, inline을 떠올리
자
01
7
2. 매크로 대신 상수 사용을 추천합니다.
- 언어 차원에서 지원하는 상수 타입의 데이터이기 때문에 기호
테이블 에 들어갑니다.
- 컴파일 된 코드가 #define을 사용한 것보다 작게 나올 수 있습
니다.
- 매크로를 쓰면 코드에 ASPECT_RATIO가 등장 횟수 만큼 사본
이 생성 되지만, 상수 타입은 여러 번 써도 사본은 딱 한 개만 생깁
#define을 쓰려거든 const, enum, inline을 떠올리
자
01
8
1. 상수 포인터를 정의하는 경우
- 상수 정의는 헤더 파일에 넣는 것이 관례이므로, 포인터는 꼭
const로 선언해 주어야 하고, 이와 더불어 포인터가 가리키는 대상
까지 const로 선언하는 것이 보통입니다.
#define을 상수로 교체하려고 할 때 주의해야 할 점
01
9
2. 클래스 멤버로 상수(클래스 상수)를 정의하는 경우
- 그 상수의 사본 개수가 한 개를 넘지 못하게 하고 싶다면 정적
멤버 (static)로 만들어야 합니다.
- 상수의 초기값은 해당 상수가 선언된 시점에서 바로 주어지기
때문에 정의에는 상수의 초기값이 있으면 안됩니다.
#define을 상수로 교체하려고 할 때 주의해야 할 점
01
10
#define을 상수로 교체하려고 할 때 주의해야 할 점
01
11
3. #define은 유효범위란 무엇인지 모릅니다.
- 매크로는 정의되면 중간에 #undef가 없다면, 컴파일이 끝날 때
까지 만 유효합니다.
- 매크로는 어떤 형태의 캡슐화 혜택도 받을 수 없습니다.
#define을 상수로 교체하려고 할 때 주의해야 할 점
01
12
나열자 타입의 값은 int가 사용되야 할 곳에서도 쓸 수 있다는 사실을 적
극 활용해봅니다.
1. 통칭 나열자 둔갑술(enum hack)으로 알려진 기법입니다.
2. 동작방식은 const보다는 #define에 더 가깝습니다.
- const는 주소를 잡아내는 게 합당하지만, enum의 주소를 취하
는 것은 합당하지 않습니다.
- enum은 #define과 같이 어떤 형태의 메모리 할당도 하지 않습
니다.
나열자(enumerator) 타입을 적극 활용하자
01
13
나열자(enumerator) 타입을 적극 활용하자
01
14
1. 매크로 함수를 사용할 경우 인자마자 반드시 괄호를 씌워줘야 합니
다.
2. 잘못된 사용이 발생할 수 있기 때문에 지양하고 있습니다.
3. 인라인 함수에 대한 템플릿을 사용하면 기존 매크로의 효율을 그대
로 유지하면서, 정규 함수의 모든 동작 방식 및 타입 안전성까지 취할 수
있습니다.
4. 템플릿 함수는 *동일 계열 함수군(Family of functions)를 만들어냅
니다.
매크로 함수를 만드려면 #define보단 inline함수
01
15
매크로 함수를 만드려면 #define보단 inline함수
01
16
함수 매크로를 사용하는 방식 인라인 함수를 이용한 템플릿
프로그래밍
KeyPoint!
1. 단순한 함수를 쓸 때는, #define보다 const 객체 혹은 enum을 우선
생각하자.
2. 함수처럼 쓰이는 매크로를 만드려면, #define보다 inline 함수를 우
선 생각하자.
매크로 함수를 만드려면 #define보단 inline함수
01
17
낌새만 보이면 const를 들이대보자!
Const의 의미로는..
1. 외부 변경을 불가능하게 하여 ‘의미적인 제약’을 소스 코드 수준에서
붙입니다.
2. 어떤 값이 불변이어야 한다는 제작자의 의도를 컴파일러 및 다른 프
로그래머와 나눌 수 있는 수단입니다.
낌새만 보이면 const를 들이대보자!
01
19
Const의 사용 가능 범위
- 클래스 외부에서는 전역 혹은 네임스페이스 유효 범위의 상수를 선언
- 파일, 함수, 블록 유효 범위에서 존재하는 정적 객체
- 클래스 내부의 정적 멤버 및 및 비정적 데이터 멤버 모두
- 포인터
낌새만 보이면 const를 들이대보자!
01
20
- 포인터가 가리키는 대상을 상수로 할 수도 있고, 포인터 자체를 상수
로 할 수도 있습니다.
낌새만 보이면 const를 들이대보자!
01
21
- 함수에서 const는 강력한 존재입니다.
- 함수 반환값을 상수로 선언하면 안전성이나 효율성을 포기하지 않고
도 버그를 예방할 수 있습니다.
낌새만 보이면 const를 들이대보자!
01
22
상수 멤버 함수
- 함수 맨 뒤에 const를 붙여서 표기합니다.
- 해당 멤버가 상수 객체에서도 호출 가능한 함수라는 뜻입니다.
- 클래스의 인터페이스를 이해하기 좋게 하는 효과가 있습니다.
- 이 키워드를 통해 상수 객체를 사용할 수 있게 하자는 뜻입니다.
낌새만 보이면 const를 들이대보자!
01
23
- 상수 객체에 대한 참조자(reference-to-const)로 진행할 때 상수 멤
버 함수가 준비되어 있어야 한다는 것이 포인트.
- C++의 성능을 높이는 핵심 기법 중 하나인 상수 객체에 대한 참조자
로 전달을 하게 될 때 전달된 ‘상수 객체’에서 사용할 멤버 함수가 있어
야 하기 때문
- const 키워드가 있고 없고의 차이만 있는 멤버 함수도 오버로딩이 가
낌새만 보이면 const를 들이대보자!
01
24
물리적 상수성[비트 수준 상수성]
- 어떤 멤버 함수가 그 객체의 어떤 데이터 멤버도 건드리지 않아야 그
멤버 함수가 ‘const’임을 인정하는 개념입니다.
- 이 때 static 멤버는 논외입니다.
- 즉, 멤버 포인터가 가리키는 대상의 수정 여부는 판단하지 않습니다.
낌새만 보이면 const를 들이대보자!
01
25
논리적 상수성
- 값이 몇 개 바뀌어도 사용자가 그걸 알 수 없고, 논리적으로 상수라면,
그것은 상수입니다.
- mutable 키워드를 사용해 상수 객체에서도 수정 가능한 멤버를 생성
할 수 있습니다.
- 컴파일러가 비트 수준 상수성을 지켜주지만, 논리적인 상수성을 사용
하면서 프로그래밍 하는 사람이 되어야 합니다.
낌새만 보이면 const를 들이대보자!
01
26
상수 멤버 및 비상수 멤버 함수의 코드 중복을 피하기 위한 방법
- 비상수 버전이 상수 버전을 호출하게 해야합니다.
- 상수 멤버에서 비상수 멤버를 호출하게 되면, 데이터를 수정하지 않
겠다고 약속한 객체를 배신하는 것이 되기 때문입니다.
- const_cast를 통해 캐스팅 하는 것은 좋지 못한 발상입니다.
- *this의 타입캐스팅을 하는 방법을 이용해 캐스팅을 한번이 아닌 두
번을 하도록 합니다.
낌새만 보이면 const를 들이대보자!
01
27
- 첫 번째로 *this에 const를 붙이는 캐스팅을 하고,
- 두 번째로 상수 반환 값에서 const를 떼어내는 캐스팅을 합니다.
낌새만 보이면 const를 들이대보자!
01
28
KeyPoint!
- const를 붙여 선언하면 컴파일러의 도움을 받아 버그를 예방 할 수
있습니다.
- const는 어떤 유효 범위에 있는 개체, 함수 파라미터 및 반환 타입 그
리고 멤버 함수에도 붙을 수 있습니다.
- 컴파일러 쪽에서 보면 비트수준 상수성을 지켜야 하지만, 작성자인
우리는 논리적인 상수성을 사용해서 프로그래밍 해야합니다.
- 코드 중복을 피하기 위해서는 비상수 멤버가 상수 멤버를 호출하게
낌새만 보이면 const를 들이대보자!
01
29
객체를 사용하기 전에 반드시 초기화
초기화에 런타임 비용이 소모될 수 있는 상황이라면 값이 초기화 된다
는 보장이 없습니다.
- 배열(C++의 C)은 각 원소가 확실히 초기화된다는 보장이 없습니다.
- STL의 vector(C++의 STL)는 초기화가 된다는 보장을 가지고 있습니
다.
- 이렇기에 모든 객체를 사용하기 전에 항상 초기화 하는 것입니다.
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
31
대입(Assignment)을 초기화(Initialization)와 헷갈리지 않는 것이 가장
중요합니다.
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
32
대입(Assignment)을 초기화(Initialization)와 헷갈리지 않는 것이 가장 중요합
니다.
- 초기화는 생성자가 호출되기 전에 데이터 멤버의 기본 생성자가 호출되었
습니다.
- 그 중 numTimesConsulted은 기본 제공 타입의 데이터 멤버이기 떄문에 생
성자 안에서 대입되기 전에 초기화 되리란 보장이 없습니다.
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
33
초기화 리스트(Initalizer List)를 사용하시면 됩니다!
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
34
초기화 리스트(Initalizer List)를 사용하시면 됩니다!
- 데이터 멤버에 사용자가 원하는 값을 주고 시작한다는 점에서는 똑같
지만, 초기화 리스트를 사용하는 것이 더 효율적일 가능성이 큽니다.
- 기본제공 타입의 객체는 초기화와 대입에 걸리는 비용의 차이가 없지
만, 같이 초기화 리스트를 사용하는 것이 좋습니다.
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
35
초기화 리스트(Initalizer List)를 사용하시면 됩니다!
- 대입을 사용하면 기본 생성자를 호출해서 초기화를 미리 해놓은 뒤,
생성자에서 곧바로 새로운 값을 대입하는 것입니다.
=>>> 초기화 직후(데이터 멤버의 생성자) -> 대입(복사 대입 연산자
호출)
- 초기화 리스트에서 쓰이는 인자는 데이터 멤버에 대한 생성자의 인자
로 쓰이기 때문에 대입이 일어나지 않습니다.
=>>> 초기화 (복사 생성자 호출)
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
36
너무 과하다고 생각 할 수도 있습니다.
- 어떤 데이터 멤버가 초기화 리스트에 들어가지 않았고, 그 데이터 멤
버의 타입이 사용자 정의 타입이면, 컴파일러가 자동으로 그들 멤버
에 대해 기본 생성자를 호출하게 되어 있기 때문입니다.
- 어쩌다 리스트에서 멤버를 빼먹었을 때 어떤 멤버가 초기화되지 않을
수 있다는 사실을 끌고 가야 하는 부담이 없어지게 됩니다.
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
37
초기화 리스트를 사용하는 것이 선택이 아닌 의무가 될 때도 있습니다.
바로 상수나 레퍼런스로 되어 있는 데이터 멤버의 경우입니다.
- 상수와 레퍼런스는 대입 자체가 불가능 하기 때문입니다.
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
38
C++에서 객체를 구성하는 데이터의 초기화 순서는 초기화가 변덕스럽
지 않은 부분입니다.
- 기본 클래스는 파생 클래스보다 먼저 초기화 됩니다.
- 클래스 데이터 멤버는 선언된 순서대로 초기화 됩니다.
- 멤버 초기화 리스트에 넣어진 순서가 다르더라도, 초기화 순서는 그
대로입니다.
=>> 주의!!
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
39
C++에서 객체를 구성하는 데이터의 초기화 순서는 초기화가 변덕스럽
지 않은 부분입니다.
- 기본 클래스는 파생 클래스보다 먼저 초기화 됩니다.
- 클래스 데이터 멤버는 선언된 순서대로 초기화 됩니다.
- 멤버 초기화 리스트에 넣어진 순서가 다르더라도, 초기화 순서는 그
대로입니다.
=>> 주의!!
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
40
비지역 정적 객체의 초기화 순서는 개별 번역 단위에서 정해집니다.
- 정적 객체(static object)는 자신이 생성된 시점부터 프로그램이 끝날
때까지 살아있는 객체를 일컫습니다.
- 스택 / 힙 기반 객체는 정적 객체가 될 수 없습니다.
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
41
정적 객체(static object)는
1. 전역 객체
2. 네임스페이스 유효범위에서 정의된 객체
3. 클래스 안에서 static으로 선언된 객체
4. 함수 안에서 static으로 선언된 객체 (지역 정적 객체, local static
object)
5. 파일 유효범위에서 static으로 정의된 객체
=>> 1, 2, 3, 5는 비지역 정적 객체(non-local static object)
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
42
번역 단위(translation unit)는
- 컴파일을 통해 하나의 목적 파일을 만드는 바탕이 되는 코드를 말합
니다.
- 기본적으로 소스 파일 하나가 되는데, 그 파일이 #include하는 파일
들까지 합쳐서 하나의 번역 단위가 됩니다.
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
43
다시 정리하면, 서로 다른 번역 단위에서
정의된 비지역 정적 객체들의 초기화 순서
는 정해져 있지 않습니다.
- Directory 클래스의 생성자에서 비지역
정적 객체인 FileSystem에 접근하여 함수
를 호출하는 부분이 있는데, 이것이 초기
화가 되있다고 보장할 수 없습니다.
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
44
이 문제를 해결하기 위해 비지역 정적 객체를 지역
정적 객체로 바꾸면 해결 가능합니다.
=>> 함수로 호출하는 방식.
- 이 패턴이 바로 Singleton Pattern입니다.
- 지역 정적 객체는 함수 호출 중 그 객체의 정의
에 최초로 닿았을 때 초기화가 되도록 C++에서
보장해줍니다.
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
45
정적 객체 자체를 직접 사용하지 않고, 그 객체에 대한 참조자를 반환하
는 함수를 사용하도록 변경한 것입니다.
- 참조자 반환 함수는 구현이 단순하지만, 다중스레드 시스템에서는 동
작에 장애가 생길 우려가 있습니다.
- 다중스레드가 시작되기 전 미리 참조자 반환 함수를 호출하도록 합니
다.
- 초기화에 관계된 Race Condition을 예방할 수 있습니다.
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
46
KeyPoint!
- 기본제공 타입의 객체는 직접 손으로 초기화합니다.
- 생성자 안에서 대입을 통한 데이터 입력 보다는 초기화 리스트를 즐
겨 사용합니다. 그 순서도 멤버가 선언된 순서와 똑같이 하면 더 좋습
니다.
- 여러 번역단위에 있는 비지역 정적 객체들의 초기화 순서 문제는 피
해서 설계해야합니다.
객체를 사용하기 전에 반드시 그 객체를 초기화하자!
01
47
C++가 은근슬쩍 만들어 호출해버리는
함수
C++에는 클래스 안에 직접 선언하지 않으면 컴파일러가 자동으로 생성
해주는 멤버 함수들이 존재합니다.
- 생성자와 소멸자 (Constructor & desctructor)
- 복사 생성자 (Copy Constructor)
- 복사 대입 연산자 (Copy Assignment Operator)
C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을
세우자
01
49
이들은 모두 public 멤버이며, inline 함수입니다.
C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을
세우자
01
50
주의해야할 점!!
- 소멸자는 클래스가 상속한 기본 클래스의 소멸자가 가상 소멸자로 되
어 있지 않으면 비가상 소멸자로 만들어집니다.
C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을
세우자
01
51
C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을
세우자
01
52
- 클래스 안에 생성자가 존재할 경우, 컴파일러는 기본 생성자를 만들
어내지 않습니다.
- 반면, 복사 생성자와 복사 대입 연산자는 존재하지 않으므로 컴파일
러에 의해 기본형이 만들어집니다.
컴파일러가 함수를 자동으로 생성하려면 최종 결과 코드가 ‘적법(legal)
해야 하고, ‘이치에 닿아야만(reasonable)’합니다.
- 파생 클래스 쪽에서 호출할 권한이 없는 멤버 함수(private)는 컴파일
러에 의해 암시적으로 생성되는 함수를 가질 수 없습니다.
C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을
세우자
01
53
C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을
세우자
01
54
C++의 참조자는 자신이 참조하고 있는 것
과 다른 객체를 참조할 수 없습니다.
참조자를 데이터 멤버로 갖고 있는 클래스
의 대입 연산을 지원하려면, 직접 복사 대입
연산자를 정의해줘야 합니다.
KeyPoint!
- 컴파일러는 경우에 따라 클래스에 대해 기본 생성자, 복사 생성자, 복
사 대입 연산자, 소멸자를 암시적으로 만들어 놓을 수 있습니다.
C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을
세우자
01
55
참고 자료
01
56
- Effective C++ 1장~2장
http://www.yes24.com/Product/Goods/17525589
감사합니다

More Related Content

What's hot

Swift3 typecasting nested_type
Swift3 typecasting nested_typeSwift3 typecasting nested_type
Swift3 typecasting nested_typeEunjoo Im
 
Swift3 subscript inheritance initialization
Swift3 subscript inheritance initializationSwift3 subscript inheritance initialization
Swift3 subscript inheritance initializationEunjoo Im
 
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++ 4
Effective c++ 4Effective c++ 4
Effective c++ 4현찬 양
 
More effective c++ 3
More effective c++ 3More effective c++ 3
More effective c++ 3현찬 양
 
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
 
Realm.io for iOS
Realm.io for iOSRealm.io for iOS
Realm.io for iOSEunjoo Im
 
Move semantics
Move semanticsMove semantics
Move semanticsQooJuice
 
Effective c++ 2
Effective c++ 2Effective c++ 2
Effective c++ 2현찬 양
 
More effective c++ 1
More effective c++ 1More effective c++ 1
More effective c++ 1현찬 양
 
Effective c++ 1
Effective c++ 1Effective c++ 1
Effective c++ 1현찬 양
 
effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리Injae Lee
 
Java 이해하기 쉬운 코드 20210405
Java 이해하기 쉬운 코드 20210405Java 이해하기 쉬운 코드 20210405
Java 이해하기 쉬운 코드 20210405Hyosang Hong
 
More effective c++ 항목30부터
More effective c++ 항목30부터More effective c++ 항목30부터
More effective c++ 항목30부터Dong Chan Shin
 
C++ Advanced 강의 4주차
 C++ Advanced 강의 4주차 C++ Advanced 강의 4주차
C++ Advanced 강의 4주차HyunJoon Park
 
[Swift] Generics
[Swift] Generics[Swift] Generics
[Swift] GenericsBill Kim
 
Effective C++ Chaper 1
Effective C++ Chaper 1Effective C++ Chaper 1
Effective C++ Chaper 1연우 김
 

What's hot (20)

Swift3 typecasting nested_type
Swift3 typecasting nested_typeSwift3 typecasting nested_type
Swift3 typecasting nested_type
 
5 swift 기초함수
5 swift 기초함수5 swift 기초함수
5 swift 기초함수
 
Swift3 subscript inheritance initialization
Swift3 subscript inheritance initializationSwift3 subscript inheritance initialization
Swift3 subscript inheritance initialization
 
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++
 
9 swift 클로저1
9 swift 클로저19 swift 클로저1
9 swift 클로저1
 
Effective c++ 4
Effective c++ 4Effective c++ 4
Effective c++ 4
 
More effective c++ 3
More effective c++ 3More effective c++ 3
More effective c++ 3
 
More effective c++ chapter1 2_dcshin
More effective c++ chapter1 2_dcshinMore effective c++ chapter1 2_dcshin
More effective c++ chapter1 2_dcshin
 
Realm.io for iOS
Realm.io for iOSRealm.io for iOS
Realm.io for iOS
 
Move semantics
Move semanticsMove semantics
Move semantics
 
Effective c++ 2
Effective c++ 2Effective c++ 2
Effective c++ 2
 
More effective c++ 1
More effective c++ 1More effective c++ 1
More effective c++ 1
 
Effective c++ 1
Effective c++ 1Effective c++ 1
Effective c++ 1
 
effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리
 
Java 이해하기 쉬운 코드 20210405
Java 이해하기 쉬운 코드 20210405Java 이해하기 쉬운 코드 20210405
Java 이해하기 쉬운 코드 20210405
 
Java lambda
Java lambdaJava lambda
Java lambda
 
More effective c++ 항목30부터
More effective c++ 항목30부터More effective c++ 항목30부터
More effective c++ 항목30부터
 
C++ Advanced 강의 4주차
 C++ Advanced 강의 4주차 C++ Advanced 강의 4주차
C++ Advanced 강의 4주차
 
[Swift] Generics
[Swift] Generics[Swift] Generics
[Swift] Generics
 
Effective C++ Chaper 1
Effective C++ Chaper 1Effective C++ Chaper 1
Effective C++ Chaper 1
 

Similar to Effective cpp

Effective c++ 1,2
Effective c++ 1,2Effective c++ 1,2
Effective c++ 1,2세빈 정
 
Effective C++ Chapter 1 Summary
Effective C++ Chapter 1 SummaryEffective C++ Chapter 1 Summary
Effective C++ Chapter 1 SummarySeungYeonChoi10
 
Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장 Shin heemin
 
Effective c++ 정리 1~2
Effective c++ 정리 1~2Effective c++ 정리 1~2
Effective c++ 정리 1~2Injae Lee
 
Effective c++chapter1 and2
Effective c++chapter1 and2Effective c++chapter1 and2
Effective c++chapter1 and2성연 김
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Nam Hyeonuk
 
Chapter5 ~ 6
Chapter5 ~ 6Chapter5 ~ 6
Chapter5 ~ 6Injae Lee
 
M1 2 1
M1 2 1M1 2 1
M1 2 1nexthw
 
Effective STL 1~4장 정리
Effective STL 1~4장 정리Effective STL 1~4장 정리
Effective STL 1~4장 정리Shin heemin
 
Effective c++chapter4
Effective c++chapter4Effective c++chapter4
Effective c++chapter4성연 김
 
Mec++ chapter3,4
Mec++ chapter3,4Mec++ chapter3,4
Mec++ chapter3,4문익 장
 
게임프로그래밍입문 7
게임프로그래밍입문 7게임프로그래밍입문 7
게임프로그래밍입문 7Yeonah Ki
 
Ec++ 3,4 summary
Ec++ 3,4 summaryEc++ 3,4 summary
Ec++ 3,4 summarySehyeon Nam
 
M5 1 1
M5 1 1M5 1 1
M5 1 1nexthw
 
[0618구경원]초보 게임프로그래머를 위한 c++
[0618구경원]초보 게임프로그래머를 위한 c++[0618구경원]초보 게임프로그래머를 위한 c++
[0618구경원]초보 게임프로그래머를 위한 c++KyeongWon Koo
 
Effective java
Effective javaEffective java
Effective javaHaeil Yi
 
[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java유리 하
 
More effective c++ Chap1~2
More effective c++ Chap1~2More effective c++ Chap1~2
More effective c++ Chap1~2Injae Lee
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinDong Chan Shin
 

Similar to Effective cpp (20)

Effective c++ 1,2
Effective c++ 1,2Effective c++ 1,2
Effective c++ 1,2
 
Effective C++ Chapter 1 Summary
Effective C++ Chapter 1 SummaryEffective C++ Chapter 1 Summary
Effective C++ Chapter 1 Summary
 
Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장
 
Effective c++ 정리 1~2
Effective c++ 정리 1~2Effective c++ 정리 1~2
Effective c++ 정리 1~2
 
Effective c++chapter1 and2
Effective c++chapter1 and2Effective c++chapter1 and2
Effective c++chapter1 and2
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약
 
Chapter5 ~ 6
Chapter5 ~ 6Chapter5 ~ 6
Chapter5 ~ 6
 
M1 2 1
M1 2 1M1 2 1
M1 2 1
 
1 2 1
1 2 11 2 1
1 2 1
 
Effective STL 1~4장 정리
Effective STL 1~4장 정리Effective STL 1~4장 정리
Effective STL 1~4장 정리
 
Effective c++chapter4
Effective c++chapter4Effective c++chapter4
Effective c++chapter4
 
Mec++ chapter3,4
Mec++ chapter3,4Mec++ chapter3,4
Mec++ chapter3,4
 
게임프로그래밍입문 7
게임프로그래밍입문 7게임프로그래밍입문 7
게임프로그래밍입문 7
 
Ec++ 3,4 summary
Ec++ 3,4 summaryEc++ 3,4 summary
Ec++ 3,4 summary
 
M5 1 1
M5 1 1M5 1 1
M5 1 1
 
[0618구경원]초보 게임프로그래머를 위한 c++
[0618구경원]초보 게임프로그래머를 위한 c++[0618구경원]초보 게임프로그래머를 위한 c++
[0618구경원]초보 게임프로그래머를 위한 c++
 
Effective java
Effective javaEffective java
Effective java
 
[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java
 
More effective c++ Chap1~2
More effective c++ Chap1~2More effective c++ Chap1~2
More effective c++ Chap1~2
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshin
 

More from TonyCms

Unreal_SubSystem.pptx
Unreal_SubSystem.pptxUnreal_SubSystem.pptx
Unreal_SubSystem.pptxTonyCms
 
Unreal_GameAbilitySystem.pptx
Unreal_GameAbilitySystem.pptxUnreal_GameAbilitySystem.pptx
Unreal_GameAbilitySystem.pptxTonyCms
 
AAA게임_UI_최적화_및_빌드하기.pptx
AAA게임_UI_최적화_및_빌드하기.pptxAAA게임_UI_최적화_및_빌드하기.pptx
AAA게임_UI_최적화_및_빌드하기.pptxTonyCms
 
Unreal python
Unreal pythonUnreal python
Unreal pythonTonyCms
 
Unreal animation system
Unreal animation systemUnreal animation system
Unreal animation systemTonyCms
 
언리얼을 활용한 오브젝트 풀링
언리얼을 활용한 오브젝트 풀링언리얼을 활용한 오브젝트 풀링
언리얼을 활용한 오브젝트 풀링TonyCms
 
Unreal perception
Unreal perceptionUnreal perception
Unreal perceptionTonyCms
 
About matinee
About matineeAbout matinee
About matineeTonyCms
 
GameInstance에 대해서 알아보자
GameInstance에 대해서 알아보자GameInstance에 대해서 알아보자
GameInstance에 대해서 알아보자TonyCms
 
읽기 좋은 코드가 좋은 코드다.
읽기 좋은 코드가 좋은 코드다.읽기 좋은 코드가 좋은 코드다.
읽기 좋은 코드가 좋은 코드다.TonyCms
 
Cascade Shadow Map
Cascade Shadow MapCascade Shadow Map
Cascade Shadow MapTonyCms
 

More from TonyCms (11)

Unreal_SubSystem.pptx
Unreal_SubSystem.pptxUnreal_SubSystem.pptx
Unreal_SubSystem.pptx
 
Unreal_GameAbilitySystem.pptx
Unreal_GameAbilitySystem.pptxUnreal_GameAbilitySystem.pptx
Unreal_GameAbilitySystem.pptx
 
AAA게임_UI_최적화_및_빌드하기.pptx
AAA게임_UI_최적화_및_빌드하기.pptxAAA게임_UI_최적화_및_빌드하기.pptx
AAA게임_UI_최적화_및_빌드하기.pptx
 
Unreal python
Unreal pythonUnreal python
Unreal python
 
Unreal animation system
Unreal animation systemUnreal animation system
Unreal animation system
 
언리얼을 활용한 오브젝트 풀링
언리얼을 활용한 오브젝트 풀링언리얼을 활용한 오브젝트 풀링
언리얼을 활용한 오브젝트 풀링
 
Unreal perception
Unreal perceptionUnreal perception
Unreal perception
 
About matinee
About matineeAbout matinee
About matinee
 
GameInstance에 대해서 알아보자
GameInstance에 대해서 알아보자GameInstance에 대해서 알아보자
GameInstance에 대해서 알아보자
 
읽기 좋은 코드가 좋은 코드다.
읽기 좋은 코드가 좋은 코드다.읽기 좋은 코드가 좋은 코드다.
읽기 좋은 코드가 좋은 코드다.
 
Cascade Shadow Map
Cascade Shadow MapCascade Shadow Map
Cascade Shadow Map
 

Effective cpp

  • 2. C++를 언어들의 연합체로 바라보는 안목은 필수 #define을 쓰려거든 const, enum, inline을 떠올리자 낌새만 보이면 const를 들이대보자! 객체를 사용하기 전에 반드시 그 객체를 초기화 하자! C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세 우자 Index 01 02 03 04 05
  • 3. C++에 왔으면 C++의 법을 따릅시다
  • 4. C++는 다중패러다임 프로그래밍 언어로 불립니다. - 절차적(Procedural) 프로그래밍을 기본으로 하여 - 객체 지향 (object – oriented) - 함수식 (functional) - 일반화 (Generic) - 메타프로그래밍 (metaProgramming) C++를 언어들의 연합체로 바라보는 안목은 필수 01 4
  • 5. C++는 한가지 프로그래밍 규칙 아래 있는 통합 언어가 아니라, 4개의 하위언어(Sub Language)를 제공하는 연합체로 구성되어 있습니다. - C : C++는 C를 기본으로 하고 있습니다. - 객체 지향 : 클래스, 캡슐화, 다형성, 가상 함수(동적 바인딩) - 템플릿 C++ : 일반화 프로그래밍, 템플릿 메타 프로그래밍 (TMP) - STL : 템플릿 라이브러리, 컨테이너, 반복자, 알고리즘, 함수 객체 C++를 언어들의 연합체로 바라보는 안목은 필수 01 5
  • 6. #define을 쓰려거든 const, enum, inline을 떠올리자
  • 7. 가급적 선행 처리자보다 컴파일러를 더 가까이 하자. 1. #define ASPECT_RATIO 1.653 - define을 사용할 경우 사용자에겐 기호식 이름으로 보이지만, 컴파일 러는 선행 처리자가 숫자 상수로 바꾸기 때문에 ASPECT_RATIO라는 이름은 컴파일러가 쓰는 기호 테이블에 들어 가지 않게 됩니다. - 에러가 발생하게 될 경우 에러 메시지가 ASPECT_RATIO가 아 #define을 쓰려거든 const, enum, inline을 떠올리 자 01 7
  • 8. 2. 매크로 대신 상수 사용을 추천합니다. - 언어 차원에서 지원하는 상수 타입의 데이터이기 때문에 기호 테이블 에 들어갑니다. - 컴파일 된 코드가 #define을 사용한 것보다 작게 나올 수 있습 니다. - 매크로를 쓰면 코드에 ASPECT_RATIO가 등장 횟수 만큼 사본 이 생성 되지만, 상수 타입은 여러 번 써도 사본은 딱 한 개만 생깁 #define을 쓰려거든 const, enum, inline을 떠올리 자 01 8
  • 9. 1. 상수 포인터를 정의하는 경우 - 상수 정의는 헤더 파일에 넣는 것이 관례이므로, 포인터는 꼭 const로 선언해 주어야 하고, 이와 더불어 포인터가 가리키는 대상 까지 const로 선언하는 것이 보통입니다. #define을 상수로 교체하려고 할 때 주의해야 할 점 01 9
  • 10. 2. 클래스 멤버로 상수(클래스 상수)를 정의하는 경우 - 그 상수의 사본 개수가 한 개를 넘지 못하게 하고 싶다면 정적 멤버 (static)로 만들어야 합니다. - 상수의 초기값은 해당 상수가 선언된 시점에서 바로 주어지기 때문에 정의에는 상수의 초기값이 있으면 안됩니다. #define을 상수로 교체하려고 할 때 주의해야 할 점 01 10
  • 11. #define을 상수로 교체하려고 할 때 주의해야 할 점 01 11
  • 12. 3. #define은 유효범위란 무엇인지 모릅니다. - 매크로는 정의되면 중간에 #undef가 없다면, 컴파일이 끝날 때 까지 만 유효합니다. - 매크로는 어떤 형태의 캡슐화 혜택도 받을 수 없습니다. #define을 상수로 교체하려고 할 때 주의해야 할 점 01 12
  • 13. 나열자 타입의 값은 int가 사용되야 할 곳에서도 쓸 수 있다는 사실을 적 극 활용해봅니다. 1. 통칭 나열자 둔갑술(enum hack)으로 알려진 기법입니다. 2. 동작방식은 const보다는 #define에 더 가깝습니다. - const는 주소를 잡아내는 게 합당하지만, enum의 주소를 취하 는 것은 합당하지 않습니다. - enum은 #define과 같이 어떤 형태의 메모리 할당도 하지 않습 니다. 나열자(enumerator) 타입을 적극 활용하자 01 13
  • 15. 1. 매크로 함수를 사용할 경우 인자마자 반드시 괄호를 씌워줘야 합니 다. 2. 잘못된 사용이 발생할 수 있기 때문에 지양하고 있습니다. 3. 인라인 함수에 대한 템플릿을 사용하면 기존 매크로의 효율을 그대 로 유지하면서, 정규 함수의 모든 동작 방식 및 타입 안전성까지 취할 수 있습니다. 4. 템플릿 함수는 *동일 계열 함수군(Family of functions)를 만들어냅 니다. 매크로 함수를 만드려면 #define보단 inline함수 01 15
  • 16. 매크로 함수를 만드려면 #define보단 inline함수 01 16 함수 매크로를 사용하는 방식 인라인 함수를 이용한 템플릿 프로그래밍
  • 17. KeyPoint! 1. 단순한 함수를 쓸 때는, #define보다 const 객체 혹은 enum을 우선 생각하자. 2. 함수처럼 쓰이는 매크로를 만드려면, #define보다 inline 함수를 우 선 생각하자. 매크로 함수를 만드려면 #define보단 inline함수 01 17
  • 18. 낌새만 보이면 const를 들이대보자!
  • 19. Const의 의미로는.. 1. 외부 변경을 불가능하게 하여 ‘의미적인 제약’을 소스 코드 수준에서 붙입니다. 2. 어떤 값이 불변이어야 한다는 제작자의 의도를 컴파일러 및 다른 프 로그래머와 나눌 수 있는 수단입니다. 낌새만 보이면 const를 들이대보자! 01 19
  • 20. Const의 사용 가능 범위 - 클래스 외부에서는 전역 혹은 네임스페이스 유효 범위의 상수를 선언 - 파일, 함수, 블록 유효 범위에서 존재하는 정적 객체 - 클래스 내부의 정적 멤버 및 및 비정적 데이터 멤버 모두 - 포인터 낌새만 보이면 const를 들이대보자! 01 20
  • 21. - 포인터가 가리키는 대상을 상수로 할 수도 있고, 포인터 자체를 상수 로 할 수도 있습니다. 낌새만 보이면 const를 들이대보자! 01 21
  • 22. - 함수에서 const는 강력한 존재입니다. - 함수 반환값을 상수로 선언하면 안전성이나 효율성을 포기하지 않고 도 버그를 예방할 수 있습니다. 낌새만 보이면 const를 들이대보자! 01 22
  • 23. 상수 멤버 함수 - 함수 맨 뒤에 const를 붙여서 표기합니다. - 해당 멤버가 상수 객체에서도 호출 가능한 함수라는 뜻입니다. - 클래스의 인터페이스를 이해하기 좋게 하는 효과가 있습니다. - 이 키워드를 통해 상수 객체를 사용할 수 있게 하자는 뜻입니다. 낌새만 보이면 const를 들이대보자! 01 23
  • 24. - 상수 객체에 대한 참조자(reference-to-const)로 진행할 때 상수 멤 버 함수가 준비되어 있어야 한다는 것이 포인트. - C++의 성능을 높이는 핵심 기법 중 하나인 상수 객체에 대한 참조자 로 전달을 하게 될 때 전달된 ‘상수 객체’에서 사용할 멤버 함수가 있어 야 하기 때문 - const 키워드가 있고 없고의 차이만 있는 멤버 함수도 오버로딩이 가 낌새만 보이면 const를 들이대보자! 01 24
  • 25. 물리적 상수성[비트 수준 상수성] - 어떤 멤버 함수가 그 객체의 어떤 데이터 멤버도 건드리지 않아야 그 멤버 함수가 ‘const’임을 인정하는 개념입니다. - 이 때 static 멤버는 논외입니다. - 즉, 멤버 포인터가 가리키는 대상의 수정 여부는 판단하지 않습니다. 낌새만 보이면 const를 들이대보자! 01 25
  • 26. 논리적 상수성 - 값이 몇 개 바뀌어도 사용자가 그걸 알 수 없고, 논리적으로 상수라면, 그것은 상수입니다. - mutable 키워드를 사용해 상수 객체에서도 수정 가능한 멤버를 생성 할 수 있습니다. - 컴파일러가 비트 수준 상수성을 지켜주지만, 논리적인 상수성을 사용 하면서 프로그래밍 하는 사람이 되어야 합니다. 낌새만 보이면 const를 들이대보자! 01 26
  • 27. 상수 멤버 및 비상수 멤버 함수의 코드 중복을 피하기 위한 방법 - 비상수 버전이 상수 버전을 호출하게 해야합니다. - 상수 멤버에서 비상수 멤버를 호출하게 되면, 데이터를 수정하지 않 겠다고 약속한 객체를 배신하는 것이 되기 때문입니다. - const_cast를 통해 캐스팅 하는 것은 좋지 못한 발상입니다. - *this의 타입캐스팅을 하는 방법을 이용해 캐스팅을 한번이 아닌 두 번을 하도록 합니다. 낌새만 보이면 const를 들이대보자! 01 27
  • 28. - 첫 번째로 *this에 const를 붙이는 캐스팅을 하고, - 두 번째로 상수 반환 값에서 const를 떼어내는 캐스팅을 합니다. 낌새만 보이면 const를 들이대보자! 01 28
  • 29. KeyPoint! - const를 붙여 선언하면 컴파일러의 도움을 받아 버그를 예방 할 수 있습니다. - const는 어떤 유효 범위에 있는 개체, 함수 파라미터 및 반환 타입 그 리고 멤버 함수에도 붙을 수 있습니다. - 컴파일러 쪽에서 보면 비트수준 상수성을 지켜야 하지만, 작성자인 우리는 논리적인 상수성을 사용해서 프로그래밍 해야합니다. - 코드 중복을 피하기 위해서는 비상수 멤버가 상수 멤버를 호출하게 낌새만 보이면 const를 들이대보자! 01 29
  • 30. 객체를 사용하기 전에 반드시 초기화
  • 31. 초기화에 런타임 비용이 소모될 수 있는 상황이라면 값이 초기화 된다 는 보장이 없습니다. - 배열(C++의 C)은 각 원소가 확실히 초기화된다는 보장이 없습니다. - STL의 vector(C++의 STL)는 초기화가 된다는 보장을 가지고 있습니 다. - 이렇기에 모든 객체를 사용하기 전에 항상 초기화 하는 것입니다. 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 31
  • 32. 대입(Assignment)을 초기화(Initialization)와 헷갈리지 않는 것이 가장 중요합니다. 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 32
  • 33. 대입(Assignment)을 초기화(Initialization)와 헷갈리지 않는 것이 가장 중요합 니다. - 초기화는 생성자가 호출되기 전에 데이터 멤버의 기본 생성자가 호출되었 습니다. - 그 중 numTimesConsulted은 기본 제공 타입의 데이터 멤버이기 떄문에 생 성자 안에서 대입되기 전에 초기화 되리란 보장이 없습니다. 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 33
  • 34. 초기화 리스트(Initalizer List)를 사용하시면 됩니다! 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 34
  • 35. 초기화 리스트(Initalizer List)를 사용하시면 됩니다! - 데이터 멤버에 사용자가 원하는 값을 주고 시작한다는 점에서는 똑같 지만, 초기화 리스트를 사용하는 것이 더 효율적일 가능성이 큽니다. - 기본제공 타입의 객체는 초기화와 대입에 걸리는 비용의 차이가 없지 만, 같이 초기화 리스트를 사용하는 것이 좋습니다. 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 35
  • 36. 초기화 리스트(Initalizer List)를 사용하시면 됩니다! - 대입을 사용하면 기본 생성자를 호출해서 초기화를 미리 해놓은 뒤, 생성자에서 곧바로 새로운 값을 대입하는 것입니다. =>>> 초기화 직후(데이터 멤버의 생성자) -> 대입(복사 대입 연산자 호출) - 초기화 리스트에서 쓰이는 인자는 데이터 멤버에 대한 생성자의 인자 로 쓰이기 때문에 대입이 일어나지 않습니다. =>>> 초기화 (복사 생성자 호출) 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 36
  • 37. 너무 과하다고 생각 할 수도 있습니다. - 어떤 데이터 멤버가 초기화 리스트에 들어가지 않았고, 그 데이터 멤 버의 타입이 사용자 정의 타입이면, 컴파일러가 자동으로 그들 멤버 에 대해 기본 생성자를 호출하게 되어 있기 때문입니다. - 어쩌다 리스트에서 멤버를 빼먹었을 때 어떤 멤버가 초기화되지 않을 수 있다는 사실을 끌고 가야 하는 부담이 없어지게 됩니다. 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 37
  • 38. 초기화 리스트를 사용하는 것이 선택이 아닌 의무가 될 때도 있습니다. 바로 상수나 레퍼런스로 되어 있는 데이터 멤버의 경우입니다. - 상수와 레퍼런스는 대입 자체가 불가능 하기 때문입니다. 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 38
  • 39. C++에서 객체를 구성하는 데이터의 초기화 순서는 초기화가 변덕스럽 지 않은 부분입니다. - 기본 클래스는 파생 클래스보다 먼저 초기화 됩니다. - 클래스 데이터 멤버는 선언된 순서대로 초기화 됩니다. - 멤버 초기화 리스트에 넣어진 순서가 다르더라도, 초기화 순서는 그 대로입니다. =>> 주의!! 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 39
  • 40. C++에서 객체를 구성하는 데이터의 초기화 순서는 초기화가 변덕스럽 지 않은 부분입니다. - 기본 클래스는 파생 클래스보다 먼저 초기화 됩니다. - 클래스 데이터 멤버는 선언된 순서대로 초기화 됩니다. - 멤버 초기화 리스트에 넣어진 순서가 다르더라도, 초기화 순서는 그 대로입니다. =>> 주의!! 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 40
  • 41. 비지역 정적 객체의 초기화 순서는 개별 번역 단위에서 정해집니다. - 정적 객체(static object)는 자신이 생성된 시점부터 프로그램이 끝날 때까지 살아있는 객체를 일컫습니다. - 스택 / 힙 기반 객체는 정적 객체가 될 수 없습니다. 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 41
  • 42. 정적 객체(static object)는 1. 전역 객체 2. 네임스페이스 유효범위에서 정의된 객체 3. 클래스 안에서 static으로 선언된 객체 4. 함수 안에서 static으로 선언된 객체 (지역 정적 객체, local static object) 5. 파일 유효범위에서 static으로 정의된 객체 =>> 1, 2, 3, 5는 비지역 정적 객체(non-local static object) 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 42
  • 43. 번역 단위(translation unit)는 - 컴파일을 통해 하나의 목적 파일을 만드는 바탕이 되는 코드를 말합 니다. - 기본적으로 소스 파일 하나가 되는데, 그 파일이 #include하는 파일 들까지 합쳐서 하나의 번역 단위가 됩니다. 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 43
  • 44. 다시 정리하면, 서로 다른 번역 단위에서 정의된 비지역 정적 객체들의 초기화 순서 는 정해져 있지 않습니다. - Directory 클래스의 생성자에서 비지역 정적 객체인 FileSystem에 접근하여 함수 를 호출하는 부분이 있는데, 이것이 초기 화가 되있다고 보장할 수 없습니다. 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 44
  • 45. 이 문제를 해결하기 위해 비지역 정적 객체를 지역 정적 객체로 바꾸면 해결 가능합니다. =>> 함수로 호출하는 방식. - 이 패턴이 바로 Singleton Pattern입니다. - 지역 정적 객체는 함수 호출 중 그 객체의 정의 에 최초로 닿았을 때 초기화가 되도록 C++에서 보장해줍니다. 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 45
  • 46. 정적 객체 자체를 직접 사용하지 않고, 그 객체에 대한 참조자를 반환하 는 함수를 사용하도록 변경한 것입니다. - 참조자 반환 함수는 구현이 단순하지만, 다중스레드 시스템에서는 동 작에 장애가 생길 우려가 있습니다. - 다중스레드가 시작되기 전 미리 참조자 반환 함수를 호출하도록 합니 다. - 초기화에 관계된 Race Condition을 예방할 수 있습니다. 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 46
  • 47. KeyPoint! - 기본제공 타입의 객체는 직접 손으로 초기화합니다. - 생성자 안에서 대입을 통한 데이터 입력 보다는 초기화 리스트를 즐 겨 사용합니다. 그 순서도 멤버가 선언된 순서와 똑같이 하면 더 좋습 니다. - 여러 번역단위에 있는 비지역 정적 객체들의 초기화 순서 문제는 피 해서 설계해야합니다. 객체를 사용하기 전에 반드시 그 객체를 초기화하자! 01 47
  • 48. C++가 은근슬쩍 만들어 호출해버리는 함수
  • 49. C++에는 클래스 안에 직접 선언하지 않으면 컴파일러가 자동으로 생성 해주는 멤버 함수들이 존재합니다. - 생성자와 소멸자 (Constructor & desctructor) - 복사 생성자 (Copy Constructor) - 복사 대입 연산자 (Copy Assignment Operator) C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자 01 49
  • 50. 이들은 모두 public 멤버이며, inline 함수입니다. C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자 01 50
  • 51. 주의해야할 점!! - 소멸자는 클래스가 상속한 기본 클래스의 소멸자가 가상 소멸자로 되 어 있지 않으면 비가상 소멸자로 만들어집니다. C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자 01 51
  • 52. C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자 01 52 - 클래스 안에 생성자가 존재할 경우, 컴파일러는 기본 생성자를 만들 어내지 않습니다. - 반면, 복사 생성자와 복사 대입 연산자는 존재하지 않으므로 컴파일 러에 의해 기본형이 만들어집니다.
  • 53. 컴파일러가 함수를 자동으로 생성하려면 최종 결과 코드가 ‘적법(legal) 해야 하고, ‘이치에 닿아야만(reasonable)’합니다. - 파생 클래스 쪽에서 호출할 권한이 없는 멤버 함수(private)는 컴파일 러에 의해 암시적으로 생성되는 함수를 가질 수 없습니다. C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자 01 53
  • 54. C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자 01 54 C++의 참조자는 자신이 참조하고 있는 것 과 다른 객체를 참조할 수 없습니다. 참조자를 데이터 멤버로 갖고 있는 클래스 의 대입 연산을 지원하려면, 직접 복사 대입 연산자를 정의해줘야 합니다.
  • 55. KeyPoint! - 컴파일러는 경우에 따라 클래스에 대해 기본 생성자, 복사 생성자, 복 사 대입 연산자, 소멸자를 암시적으로 만들어 놓을 수 있습니다. C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자 01 55
  • 56. 참고 자료 01 56 - Effective C++ 1장~2장 http://www.yes24.com/Product/Goods/17525589