[The C++ Programming Language에서 발췌]


    어떤 객체의 초기화 식이 지정되면 해당 객체의 초기 값이 결정된다. 초기화 식은 4가지 문법 스타일 중 하나를 사용한다.


    1
    2
    3
    4
    int a1 { 1 };
    int a2 = { 1 };
    int a3 = 1;
    int a4(1);
    cs

     

    이들 중 첫 번째 항목만이 모든 상황에서 사용될 수 있으므로, 그것을 사용하기를 강력히 권장한다. 다른 후보들보다 좀 더 명확하며, 오류에 취약하지 않다.


    {}를 사용한 초기화, 리스트 초기화는 축소를 허용하지 않는다.

     정수는 자신의 값을 보관할 수 없는 또 다른 정수로 변환될 수 없다. 예를 들어 char에서 int로의 변환은 허용되지만, int에서 char는 허용되지 않는다.

    ● 부동소수점 값은 자신의 값을 보관할 수 없는 또 다른 부동소수점 타입으로 변환될 수 없다. 예를 들어 float에서 double로의 변환은 허용되지만, double에서 float는 허용되지 않는다.

    ● 부동소수점 값은 정수 타입으로 변환될 수 없다.

    ● 정수 값은 부동소수점 타입으로 변환될 수 없다.


    예를 들면 다음과 같다.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void f(double val, int val2)
    {
        int x2 = val;    // val == 7.9라면 x2는 7이 된다.
        int c2 = val2;   // val2 == 1025라면 c2는 1이 된다.
     
        int x3 { val };  // 오류 : 손실 가능성
        int c3 { val2 }; // 오류 : 축소 가능성
     
        char c4 { 24 };  // OK : 24는 char로 정확히 표시될 수 있다.
        char c5 { 264 }; // 오류(char가 8비트라 가정할 경우} : 264는 char로 표시될 수 있다.
     
        int x4 { 2.0 };  // 오류 : double에서 int 값으로 변환은 불가능
    }
    cs


    초기화 식에 의해 결정된 타입을 구하기 위해 auto를 사용할 때는 {} 초기화 식 사용에 이점이 없다. 초기화 식이 {} 리스트일 경우 우리는 리스트의 타입이 추정되기를 원하지 않을지도 모르기 때문이다. 예를 들어 다음과 같다.


    1
    2
    auto z1 { 99 }; // z1은 initializer_list<int>
    auto z2 = 99;   // z2는 int
    cs

     

    따라서 auto를 사용할 때는 =가 바람직하다.


    빈 초기화 식 리스트 {}는 기본 값을 넣겠다는 의미를 나타내는 데 사용된다. 예를 들면 다음과 같다.


    1
    2
    3
    4
    5
    int x4 {};
    double d4 {};
    char* p {};
    vector<int> v4{};
    string s4 {};
    cs


    대부분의 타입은 기본 값을 갖고 있다. 통합 정수 타입의 경우에는 기본 값으로 0을 적절히 표시한다. 포인터의 경우에는 기본 값이 nullptr이다. 사용자 정의 타입에서는 기본 값이 존재할 경우 해당 타입의 생정자에 의해 결정된다.

    Posted by Muramasa