C++11부터 도입된 중괄호 {} 초기화는 초기화 방식의 일관성을 제공하고, 축소 변환 방지 등의 장점을 가집니다.
이 문법을 활용하면 기존의 다양한 초기화 방식(=, ())을 더 직관적으로 표현할 수 있으며, 벡터(vector) 등의 컨테이너 초기화에도 유용합니다.
이 문서에서는 중괄호 초기화의 필요성, 장점, 단점, 활용법을 정리하고, 예제 코드와 함께 분석하겠습니다.
#include <iostream>
#include <vector>
using namespace std;
class Knight {
public:
Knight() { } // 기본 생성자
Knight(int a, int b) {
cout << "Knight(int, int)" << endl;
}
// 중괄호 초기화가 호출하는 생성자 (우선순위 높음)
Knight(initializer_list<int> li) {
cout << "Knight(initializer_list)" << endl;
}
};
✅ 클래스 Knight의 생성자
1. Knight() → 기본 생성자
2. Knight(int, int) → 두 개의 int를 받는 생성자
3. Knight(initializer_list<int>) → 중괄호 {} 초기화가 호출하는 생성자
initializer_list를 인자로 받으면, 중괄호 {} 초기화 시 가장 우선적으로 호출됨 int main()
{
// 다양한 초기화 방식
int a = 0; // 일반적인 대입 초기화
int b(0); // 소괄호 초기화
int c{ 0 }; // 중괄호 초기화
}
✅ 다양한 초기화 방법
= : 일반적인 대입 초기화 () : 생성자 호출을 통한 초기화 {} : C++11 이후 지원되는 중괄호 초기화 🎯 c{ 0 };의 장점
Knight k1; // 기본 생성자 호출
Knight k2 = k1; // 복사 생성자 (대입 연산자가 아님)
✅ Knight k2 = k1;
k2를 k1으로 초기화 (대입 연산자가 아님) Knight k3; // 기본 생성자
k3 = k1; // 대입 연산자 호출
✅ k3 = k1;
k3를 기본 생성자로 생성한 후, k1의 데이터를 복사 =)가 호출됨 Knight k4{ k2 };
✅ Knight k4{ k2 };
initializer_list를 받을 수도 있음 initializer_list 생성자가 없으면 복사 생성자가 호출됨 vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
✅ 기존 방식 (C++98 스타일)
push_back()을 이용하여 벡터에 데이터를 추가 vector<int> v2(10, 1); // 크기 10, 모든 값 1
✅ 소괄호 초기화 (생성자 방식)
1로 초기화 vector<int> v3{ 1, 2, 3, 4 };
✅ 중괄호 {} 초기화 (추천)
int x = 0;
// double y{ x }; // 에러 발생 (축소 변환 방지)
✅ {} 초기화는 데이터 손실을 막기 위해 축소 변환을 허용하지 않음
int → double 변환은 데이터 손실 가능성이 있으므로 컴파일 에러 발생 Knight k5(); // ⚠️ 이 코드는 함수 선언!
Knight k6{ }; // ✅ 기본 생성자 호출
✅ Knight k5();
{} 사용 → Knight k6{ }; Knight k7{ 1, 2 }; // `initializer_list<int>` 생성자가 호출됨
Knight k8(1, 2); // `Knight(int, int)` 생성자가 호출됨
✅ 중괄호 초기화 시 initializer_list 생성자가 우선 호출됨
Knight k7{ 1, 2 }; → initializer_list<int> 호출 Knight k8(1, 2); → Knight(int, int) 생성자가 호출됨 🎯 해결 방법
Knight k9(1, 2); // 소괄호를 사용하면 명확하게 `Knight(int, int)` 호출
소괄호 () 초기화 (기본 추천)
vector<int>(10, 1);처럼 특정 생성자를 호출할 때 필요 중괄호 {} 초기화
vector<int> v{1, 2, 3, 4};) double d{intVal}; → 컴파일 에러) Knight k6{}; → 생성자 호출 명확함) initializer_list 생성자가 우선 호출됨에 유의