본문 바로가기
Language/effective modern C++

현대적 C++에 적응하기

by y.j 2021. 10. 17.
728x90

현대적 C++에 적응하기

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

변수를 선언한 방법은 크게 3가지이다.

int x(0);            
int y = 0;          
int z{0};           

균일 초기화(uniform initialization)
C++11은 위에서 처럼 중괄호({..})로 초기화 할 수 있는 방법이 있다.

  1. 멤버의 초기 값을 지정하는 데에도 사용 할 수 있다.
    class Widget {
    private :
     int x{0};
     int y = 0;
     int z(0);   // 오류
    }
  1. 복사 할 수 없는 객체를 초기화 할 수 있다.
std::atomic<int> ai1{ 0 };
std::atomic<int> ai2( 0 );
std::atomic<int> ai3 = 0;          // 오류
  1. 암묵적 좁히기(narrowing conversion) 변환을 방지
double x, y , z ;

int sum{ (x + y + z) }; // 형 변환 및 초기화 모두 필요
  1. 매개변수 없는 기본 생성자를 호출
Widget w2(); // 함수 호출  
Widget w3{}; // 생성자 호출
  1. 중괄호 초기화는 std::initializaer_list를 우선시 한다.
class Widget {

public :  
Widget(int i, bool b);  
Widget(int i, double d);  
Widget(std::initializer_list il);

}

위 코드에서 std::initializerlist을 항상 우선시 하기 때문에 Widget(10, 5.0)과 Widget{10, 5.0}서로 다르게 초기화 될 수 있다.
또, Widget({}), Widget{{}}을 해도 std::initializer_list의 빈 초기치 목록을 호출한다.

vector<int> v1(10,20); // 20인 요소 10개가 생성됨
vector<int> v2{10,20}; // 10, 20 2가지 요소가 생성됨

결론 : 어느 한쪽이 나쁘다기 보다는 인터페이스 설계와 프로젝트에 따라 일관성있게 사용하자

어느 하나는 중점으로 사용하고, 나머지 하나를 예외사항으로 사용하자.

 1. 중괄호 초기화

1.C++의 가장 성가신 구문해석에 도움이 됨.
2.좁히기 변환을 방지

 2. 괄호 초기화

1. std::initializer_list를 연역하는데 문제가 없다.
2. std::initializer_list 생성자가 호출되는 일이 없다.

 

728x90

댓글