본문 바로가기

Programming

이펙티브 모던 C++_2

[Effective Modern C++] 2015 스콧 마이어스 저
" C++11 과 C++ 14 를 효과적으로 사용하는 42가지 방법

 

2장

항목 5. 명시적 형식 선언보다는 auto를 선호하라

[이유]

1. 사용하기 편리하다.

2. 초기화를 강제시켜준다.

3. 클로저에서 요구되는 만큼의 메모리만 사용한다. (std::function 은 가변 가능성 때문에 힙 메모리 할당)

4. 이식성 (32 비트에서 unsigned 와 std::vector<int>size_type 은 같지만 64비트에서는..)

 

 

 

항목 6. auto가 원치 않은 형식으로 연역될 때에는 명식적 형식의 초기치를 사용하라 

auto 변수의 형식은 변수의 초기화에 쓰이는 표현식으로부터 연역된다.

 

Q. 함수 내부 구조로 잘못 연역될 수 있는 경우가 있다.

ex) 대리자 클래스, std::vector<bool>::refrence 에서 bool 하나 값을 1비트로 표현하기 때문에 첫 주소를 영역 후 offset 연산하면 다른 값을 가리키게 된다.

 

A. 형식 명시 초기치 관용구는 auto가 원하는 형식을 연역하도록 강제한다.

ex) auto temp = staic_cast<bool>(features(w)[5]);

 

 


 

3장

항목 7. 객체 생성 시 괄호와 중괄호를 구분하라

객체 생성 방법
int x{0};
int x = 0;
int x{0};
int x = {0};

[이유]

1. 중괄호 구문은 어디서나 사용 가능하다.

* 비정적 자료 맴버의 기본 초기화 값 지정
int a // 오류
int a = 0;
int a{0}
* 복사할 수 없는 객체
**atomic : 복사 불가 지정, 최적화하지 않고  어셈블리에서 수행 순서를 지키도록 강제한다. 
std::atomic<int> a{0}  
std::atomic<int> a(0)
std::atomic = 0 // 오류

2. 중괄호 구문은 좁히기 변환을 허용하지 않는다. 

ex) int a = {(double)b + (double)c} //  double의 합을 int로 표현하지 못할 수 있음

 

3. 괄호 구문은 인수가 없는 객체를 생성하려고 할 때 함수인지 변수인지 헷갈려한다. 이런 모호함을 줄일 수 있음

 

4. std::initailizer_list 를 사용할 경우  td::initailizer_list가 아니더라도 {} 중괄호를 사용하면 해당 생성자를 부른다.

암묵적인 변환을 할 수 없는 케이스 (int -> string) 의 경우에만 제대로 불러준다.

 

5.심지어 Vector의 경우 std::initializer_list 를 받는 생성자를 가지기 때문에 괄호/중괄호 일 경우 다르게 동작한다.

std::vector<int> a{10,20} // { 10,20 }

std::vector<int> a(10,20) // 값이 20인 요소 10개

 

******6.생성자를 설계할 때 클라이언트가 괄호/중괄호를 사용하느냐에 따라 서로 다른 중복 적재 버전이 선택되는 일이 없도록 한다.

 

 

 

8. 0과 NULL 보다는 nullptr을 선호하라

[이유]

1.컴파일러가 NULL에 int 이외 정수 형식을 부여할 수도 있다. 

2.포인터가 아니다. nullptr은 포인터임을 확실히 보여준다.

 

 

9. typedef 보다 별칭 선언을 선호하라

 

 

[이유]

1. 직관적이다.

typedef
std::unique_ptr<std::unordered_map<std::string, std::string>> A
별칭
using A = unique_ptr<std::unordered_map<std::string, std::string>>;

 

2. typedef는 템플릿화 할 수 없지만, 별칭 선언은 템플릿화 할 수 있다.

template<typename T> using MyAllocList = std::list<T, MyAlloc<T>>;

template<typename T> struct MyAllocList { typedef std::list<T, MyAlloc<T>> type; };

 

 

 

 

10. 범위 없는 enum보다 범위 있는 enum을 선호하라.

 

[이유]

1. 범위가 있다.

enum A{one, two, three}
enum temp = one ; // 허용
enum temp = A.one; // 허용
enum class A{one, two, three}
enum temp = one ; // 불가
enum temp = A.one; // 허용

 

2. 다른 형식으로의 전환을 막는다.  (첫 번째 항목은 암묵적으로 정수 형식으로 변환됨)

3. 전방 선언 가능

 

 

 

 

'Programming' 카테고리의 다른 글

이펙티브 모던 C++_4  (0) 2020.11.22
이펙티브 모던 C++_3  (0) 2020.11.15
이펙티브 모던 C++_1  (0) 2020.11.01
윈도우 시스템 프로그래밍_8  (0) 2020.10.25
윈도우 시스템 프로그래밍_7  (0) 2020.10.18