-
항목7. 객체 생성시 () 와 {} 를 구분하라Effective Modern C++ 2022. 7. 19. 18:08
c++11에서는 초기화 값을 괄호로 지정할 수도 있고, 등호로 지정할 수도 있고, 중괄호로 지정할 수도 있다.
int x(0); // 초기치를 괄호로 감싼 예 int y = 0; // 초기치를 "=" 다음에 지정한 예 int z{ 0 }; // 초기치를 중괄호로 감싼 예 int r = { 0 }; // "="와 중괄호로 초기치를 지정한 예등호를 사용할 때 초기화와 배정을 구분할 필요가 있다.
Widget w1; // 기본 생성자를 호출 Widget w2 = w1; // 배정이 아님; 복사 생성자를 호출 w1 = w2; // 배정; 복사 배정 연산자(operator =)를 호출여러 가지 초기화 구문이 주는 혼동을 해결하기 위해 c++11은 균일 초기화를 도입했다. (이전에는 불가능하던 서로 다른 임의의 값들을 담는 STL 컨테이너를 직접 생성할 수도 있다.)
std::vector<int> v{ 1, 3, 5 }; // v의 초기 내용은 1, 3, 5균일 초기화는 비정적 자료 멤버의 기본 초기화 값을 지정하는 데에도 사용할 수 있다. 괄호 없이 "="만 있는 구문으로도 사용할 수 있다.
class Widget { ... private: int x{ 0 }; // OK, x의 기본값은 0 int y = 0; // 역시 OK int z(0); // 오류! }반면, 복사할 수 없는 객체는 중괄호나 괄호로는 초기화할 수 있지만 "="로는 초기화할 수 없다.
std::atomic<int> ai1{ 0 }; // OK std::atomic<int> ai2(0); // OK std::atomic<int> ai3 = 0; // 오류!균일 초기화의 혁신적인 기능 하나는, 내장 기능들 사이의 암묵적 좁히기 변환을 방지해 준다는 것이다.
double x, y, z; ... int sum1{ x + y + z }; // 오류! double들의 합을 int로 표현하지 못할 수 있음괄호나 "="를 이용한 초기화는 이러한 좁히기 변환을 점검하지 않는다. ( 위와 같은 상황에선 표현식의 값이 int에 맞게 잘려나감)
인수 없이 생성자를 호출할 때 괄호는 함수를 선언하게 될 가능성이 있다.
하지만 중괄호(균일 초기화)는 그러지 않는다.Widget w1(); // Widget을 돌려주는 w1이라는 함수를 선언함하지만 이런 중괄호 초기화(균일 초기화)도 단점은 존재한다. std::initializer_list를 받는 버전의 생성자와 다른 타입을 받는 생성자가 중복 적재돼 있을 때 중괄호 초기화는 std::initializer_list를 받는 버전을 강하게 선호한다.
// (int , bool)을 받는 Widget의 생성자가 있고 // std::initializer_list<long double> 을 받는 생성자가 있다고 하자. Widget w1(10, true); // (int , bool)타입 생성자 호출 Widget w2{10, true}; // std::initializer_list<long double> 타입 생성자 호출 // (10 과 true가 long double로 변환됨)극단적인 경우로 정확히 부합하는 생성자가 있어도 std::initializer_list을 받는 생성자에 대응돼 (좁히기 변환이 불가해) 오류가 생기는 경우도 있다.
차라리 위의 코드에서 std::initializer_list 가 아닌 std::initializer_list< std::string > 을 사용하면 중복적재 문제는 해결되긴 한다. (int 와 bool은 std::string으로 변환하는 방법이 없어서)결국 괄호 - 중괄호를 너무 혼용해서 쓰지말고 자신만의 기준을 잡고 사용하자. (난 괄호를 베이스로 사용하되 컨테이너들을 다루는 경우 중괄호를 염두하겠다.)
'Effective Modern C++' 카테고리의 다른 글
항목9. typedef보다 별칭 선언을 선호하라 (0) 2022.07.20 항목8. 0과 NULL보다 nullptr을 선호하라 (0) 2022.07.20 항목5&6. auto를 선호하라 (0) 2022.07.17 항목4. 연역된 형식을 파악하는 방법 (0) 2022.07.14 항목3. decltype의 작동 방식을 숙지하라 (0) 2022.07.14