기본 멤버 초기화기(default member initializer)는 C++11의 구조로, 클래스 멤버 변수를 선언할 때 기본 값을 직접 선언할 수 있는 기능입니다. 이 기능은 종종 데이터 초기화의 다른 방법과 혼동됩니다.
초기 C++에서는 멤버를 선언할 때 직접 초기화할 수 없었습니다; 값은 오직 생성자에서(본문이나 초기화 목록에서)만 할당되었습니다. 기본 멤버 초기화기(default member initializers)의 도입(C++11)은 가독성을 개선하고 정의되지 않은 초기화로 인한 오류의 위험을 줄였습니다.
필드가 명시적으로 초기화되지 않으면 "쓰레기"(정의되지 않은) 값이 포함됩니다. 생성자 내에서의 할당은 초기화 목록에 비해 비효율적이며, 기본 멤버 초기화기를 무시하면 클래스 확장과 새로운 생성자 작성이 복잡해집니다.
간단한 값에는 기본 멤버 초기화기를 사용하고, 복잡한 경우(특히 의존적이거나 비표준 값이 필요한 경우)에는 생성자의 초기화 목록을 사용합니다.
코드 예시:
class Widget { int x = 42; // 기본 멤버 초기화기 std::string name = "default"; // 기본 멤버 초기화기 public: Widget() = default; // x=42, name="default" Widget(int xx) : x(xx), name("new") {}// x=xx, name="new" };
주요 특징:
생성자 본문 내에서 멤버가 초기화된 경우에도 기본 멤버 초기화기가 적용되나요?
답변:
아니요. 초기화 목록에 지정되지 않으면, 변수는 먼저 기본 값(default member initializer)으로 초기화된 후, 생성자 본문에서 할당이 이루어지며 이는 덜 효율적입니다.
상속 시 기본 멤버 초기화기를 가진 클래스 멤버의 초기화 순서는?
답변:
먼저 기본 클래스의 멤버들이 초기화되고, 그 다음 파생 클래스의 멤버들이 초기화됩니다; 기본 멤버 초기화기가 적용된 각 멤버는 초기화 목록이 주어진 경우 초기화 목록을 사용하고, 그렇지 않으면 기본 멤버 초기화기를 사용합니다. 초기화되지 않은 경우(예: POD)는 초기화되지 않은 상태로 남습니다. "두 번 초기화"는 발생하지 않습니다.
정적(static) 클래스 멤버에 기본 멤버 초기화기를 사용할 수 있나요?
답변:
아니요, 정적 멤버는 기본 멤버 초기화기를 통해 초기화될 수 없습니다. 클래스 외부에서 또는 C++17에서 인라인 정적(static)으로 초기화해야 합니다.
예시:
struct S { static int a = 5; // 오류! };
생성자에서 초기화가 누락된 동적 문자열을 가진 클래스. 나중에 접근 시 정의되지 않은 동작이 발생합니다.
장점:
단점:
모든 필드는 기본 멤버 초기화기를 가집니다. 필요한 경우 추가 생성자는 초기화 목록을 통해 필요한 멤버를 명시적으로 초기화합니다.
장점:
단점: