1. 생성자 본문 대입 (기존 방식)
이 방식은 생성자 본문 { } 안에서 = 연산자를 사용하여 이미 생성된 멤버 변수에 값을 대입하는 방식입니다.
class Player
{
public:
std::string name; // 복잡한 객체
int level;
// (1) 생성자 본문 대입 방식
Player(std::string n, int l)
{
// name 멤버는 여기서 'n' 값을 할당받기 전에,
// 이미 기본값("")으로 초기화된 상태입니다.
name = n; // 불필요한 대입 복사 발생
level = l;
}
};
이 방식은 초기화 후, 대입이라는 2 단계를 거치게 됩니다.
즉, name 멤버 변수가 생성자 본문이 실행되기 전에 먼저 std::string() (빈 문자열)으로 자동 초기화됩니다.
그 후, name = n; 코드를 통해 n의 값이 이미 초기화된 name에 덮어씌워지며 불필요한 자원 이동/복사가 추가로 발생합니다.
const 멤버 변수나 참조(&) 멤버는 생성 후 값을 바꿀 수 없으므로, 이 방식으로 초기화 자체가 불가능합니다.
2. 멤버 초기화 리스트 (권장 방식)
이 방식은 생성자 매개변수 뒤에 콜론 (:) 을 사용하여 멤버를 직접 초기화하는 방식입니다.
class Player
{
public:
std::string name;
int level;
// (2) 멤버 초기화 리스트 방식
// 콜론 뒤에 멤버와 값을 괄호로 묶어 나열 (쉼표 구분)
Player(std::string n, int l) : name(n), level(l)
{
// 생성자 본문({})이 실행될 때,
// name과 level은 이미 초기화가 완료된 상태입니다.
}
}
작성 방법은 생성자 뒤에 콜론 (:) 을 찍고, 초기화가 필요한 멤버(값), 멤버2(값2) 형태로 쉼표로 구분하여 나열합니다.
이 방식의 장점은 멤버 변수가 기본값 초기화 단계를 건너뛰고, 전달된 값(n, l)으로 처음부터 바로 초기화되기 때문에 보다 효율적입니다.
또한 const 멤버나 참조(&) 멤버를 포함한 모든 종류의 멤버를 올바르게 초기화할 수 있는 방식입니다.
Modern C++ : 중괄호 {}를 통한 안전성 확보
현대에 와서는 모든 초기화를 중괄호 { } 로 통일했습니다.
따라서 name, level 뒤 인자도 { } 로 감싸 주었습니다.
물론 기존 방식대로 괄호 ( ) 를 써도 무방합니다만, { } 로 썼을 때의 잇점은 인자로 넣은 타입과 선언된 타입이 다를 경우, 컴파일 에러를 발생시켜 축소 변환(Narrowing Conversion)을 원천적으로 차단합니다. 예를 들어 int 변수에 float 값을 넣으면 ( ) 방식은 안에서 int로 자동 변환되어 잘못된 값을 인지 못하게 될 수 있는 위험에 대비하기 위함입니다.
class Player
{
public:
std::string name;
int level;
// (2) 멤버 초기화 리스트 방식
// 콜론 뒤에 멤버와 값을 괄호로 묶어 나열 (쉼표 구분)
Player(std::string n, int l) : name{n}, level{l}
{
// 생성자 본문({})이 실행될 때,
// name과 level은 이미 초기화가 완료된 상태입니다.
}
}
// 기존 괄호 방식 (level(3.14f)): 3.14f가 조용히 3으로 잘려 들어감 (버그 유발 가능)
Player player ( "Hellow", 3.14f );
// - 중괄호 방식 (level{3.14f}): 컴파일 에러 발생! (개발자에게 문제 통보)
Player player { "Hellow", 3.14f };
'C++' 카테고리의 다른 글
| 참조 반환(Return by Reference)의 이해와 활용 (0) | 2026.01.27 |
|---|---|
| 베스트 프랙티스(Best Practice) : 전문적인 C++ 코드의 기준 (0) | 2026.01.10 |
| new 할당과 초기화 (0) | 2026.01.09 |
| 스택(Stack)과 힙(Heap) : 책임과 수명의 차이 (0) | 2026.01.08 |
| 복사의 종류와 차이점 (0) | 2026.01.08 |