유니폼 초기화
C++11 이전에는 타입의 초기화 방식이 일정하지 않았다.
다음은 원을 정의할 때 한 번은 구조체로, 한 번은 클래스로 작성했다.
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;
};
C++11 이전에는 CircleStruct 타입 변수와 CircleClass 타입 변수를 초기화하는 방법이 서로 달랐다.
CircleStruct myCircle1 = { 10,10,2.5 };
CircleClass myCircle2(10, 10, 2.5);
구조체에 대해서는 { ... } 문법을 적용한 반면,
클래스에 대해서는 함수 표기법인 ( ... )로 생성자를 호출한다.
그런데 C++11부터 타입을 초기화할 때 { ... } 문법을 사용하는 유니폼 초기화를 따르도록 통일됐다.
CircleStruct myCircle3 = { 10,10,2.5 };
CircleClass myCircle4 = { 10,10,2.5 };
myCircle4를 정의하는 문장이 실행될 때 CIrcleClass의 생성자가 자동으로 호출된다.
또한 다음과 같이 등호(=)를 생략해도 된다.
CircleStruct myCircle3{ 10,10,2.5 };
CircleClass myCircle4{ 10,10,2.5 };
이러한 유니폼 이니셜라이저는 구조체나 클래스뿐만 아니라 C++에 있는 모든 대상을 초기화하는데 적용된다.
int a = 3;
int b(3);
int c = {3}; // 유니폼 초기화
int d{3}; // 유니폼 초기화
유니폼 초기화는 변수를 영 초기화(제로 초기화)할 때도 적용할 수 있다.
int e{}; // 유니폼 초기화, e는 0이 된다.
유니폼 초기화를 사용하면 축소 변환(좁히기)을 방지할 수 있다.
C++에서는 암묵적으로 축소 변환될 때가 있는데, 예를 들면 다음과 같다.
void func(int i) { /* ... */ }
int main()
{
int x= 3.14;
func(3.14);
}
x에 값을 대입할 때와 func()를 호출할 때 전달한 3.14는 3으로 값이 줄어든다.
유니폼 초기화를 사용하면 x에 값을 대입하거나 func()를 호출하는 문장이 담긴 코드를
C++11 표준을 완전히 지원하는 컴파일러로 컴파일하면 반드시 에러 메시지가 생성될 수도 있다.
int x = { 3.14 }; // 축소로 인한 에러
func({3.14}); // 축소로 인한 에러
유니폼 초기화는 동적으로 할당되는 배열을 초기화할 때도 적용할 수 있다.
int* pArray = new int[4]{0, 1, 2, 3};
\또한 클래스 멤버인 배열을 생성자 이니셜라이저로 초기화할 때도 사용할 수 있다.
class MyClass
{
public:
MyClass() : mArray{ 0, 1, 2, 3 } {}
private:
int mArray[4];
};
'💻프로그래밍 내용 정리 > C++17' 카테고리의 다른 글
[C++ 1.5.1] 표준 라이브러리 (0) | 2022.08.18 |
---|---|
[C++ 1.4.1] 직접 리스트 초기화와 복제 리스트 초기화 (0) | 2022.08.18 |
[C++ 1.3.2] 클래스 사용하기 (0) | 2022.08.17 |
[C++ 1.3.1] 클래스 정의, 접근 수준(public, private), 생성자(생성자 이니셜라이저), 소멸자 (0) | 2022.08.17 |
[C++ 1.2.6] 타입 추론(auto, decltype) (0) | 2022.08.16 |