c++ 유니폼 초기화
유니폼 초기화
C++11 이전에는 타입의 초기화 방식이 일정하지 않았다. 예를 들어 다음과 같이 원을 정의할 때 한 번은 구조체로, 한 번은 클래스로 작성한 경우를 살펴보자#include <iostream>
struct CircleStruct
{
int x, y;
double radius;
};
class CircleClass
{
public:
CircleClass(int x, int y, double radius)
: mX(x), mY(y), mRadius(radius)
{
}
private:
int mX, mY;
double mRadius;
};
int main(int argc, char *argv[])
{
CircleStruct mCircie1 = {10, 10, 2.5};
CircleClass mCircle2(10, 10, 2.5);
return 0;
}
CircleStruct myCircle3 = {10, 10, 2.5};
CircleClass myCircle4 = {10, 10, 2.5};
CircleStruct myCircle3{10, 10, 2.5};
CircleClass myCircle4{10, 10, 2.5};
C++ 모든 대상
이러한 uniform initializer는 구조체나 클래스뿐만 아니라 C++의 모든 대상을 초기화 하는데 사용 될 수 있다. 물론 유니폼 초기화로 영 초기화(zero initialization)를 할 때도 적용 가능하다. 아래와 같다.int a = 3;
int b(3);
int c = {3}; // uniform initialization, 복제 초기화
int d{3}; // uniform initialization, 직접 초기화
int e{}; // zero initialization
축소 변환
유니폼 초기화를 사용하면 축소 변환 (narrow - 좁히기)을 방지할 수 있다. C++ 에서는 암묵적으로 축소 변활될 때가 있는데, 예를 들면 다음과 같다.#include <iostream>
void func(int i) {/* ... */}
int main(int argc, char *argv[])
{
int x = 1.2345;
func(1.1234);
return 0;
}
x
에 값을 대입할 때와 func()
를 호출할 때 전달한 1.234는 3으로 값이 줄어든다. 물론 컴파일러가 요놈을 잡았다! 라고 알려줄 경고 메세지를 날려 주기도 한다.
/Users/colson/workspace/colson-log/c,c++/uniform initialization/ex2.cpp:18:14: warning: implicit conversion from 'double' to 'int' changes value from 1.2345 to 1 [-Wliteral-conversion]
int x = 1.2345;
~ ^~~~~~
/Users/colson/workspace/colson-log/c,c++/uniform initialization/ex2.cpp:19:11: warning: implicit conversion from 'double' to 'int' changes value from 1.1234 to 1 [-Wliteral-conversion]
func(1.1234);
~~~~ ^~~~~~
2 warnings generated.
그렇다면 유니폼 초기화를 사용하여 값을 대입하거나 함수를 호출할 때는 어떻게 될까? 답은 아래와 같다.

동적 배열 초기화
동적으로 할당되는 배열을 초기화할 때도 적용할 수 있다.int *pArray = new int[4]{0, 1, 2, 3};
class Myclass
{
public:
Myclass() : mArray{1, 3, 4, 5} {}
private:
int mArray[4];
};
리스트 초기화
이니셜라이져는 두가지가 있다. 이니셜라이져 리스트를 중괄호로 묵어서 표현한다.-
복제 리스트 초기화(copy list initialization):
obj = {arg1, arg2, ...};
-
직접 리스트 초기화(direct list initialization):
T obj {arg1, arg2, ...};
int main(int argc, char *argv[])
{
// copy list initialization
auto a = {11}; // C++11,C++14,C++17: initialization_list<>
auto b = {1234, 434}; // C++11,C++14,C++17: initialization_list<>
// direct list initialization
auto c {11}; // C++11,C++14: initialization_list<>, C++17: int 로 초기화
auto d {123, 321}; // C++11,C++14: initialization_list<>, C++17: Initializer for variable 'd' with type 'auto' contains multiple expressions
}
NOTE_ 복제 리스트 초기화에서 중괄호 안에 나온 원소는 반드시 타입이 모두 같아야 한다.
auto b = {11, 1.1234}
과 같은 코드를 작성하면 에러가 뿜뿜한다.
참고
- code example
- 전문가를 위한 C++