[C++20 새기능 소개] 지정 초기화자(Designated Initializers)

C++20의 새로운 기능들을 소개하는 시리즈의 여섯 번째 글에 오신 것을 환영합니다. 이번 글에서는 구조체와 클래스를 더욱 편리하게 초기화할 수 있는 지정 초기화자(Designated Initializers)에 대해 자세히 알아보겠습니다.

지정 초기화자(Designated Initializers)란 무엇인가요?

지정 초기화자는 C++20에서 도입된 기능으로, 구조체나 클래스의 멤버를 초기화할 때 멤버의 이름을 지정하여 초기화할 수 있게 해줍니다. 이는 C99에서 도입된 지정 초기화자를 C++에서도 사용할 수 있게 한 것으로, 복잡한 객체 초기화를 더욱 명확하고 간결하게 할 수 있습니다.

왜 지정 초기화자를 사용해야 할까요?

기존의 구조체나 클래스 초기화는 멤버의 순서에 의존하며, 모든 멤버를 정확한 순서대로 초기화해야 했습니다. 이는 멤버의 개수가 많거나 일부 멤버만 초기화하려는 경우 불편함을 초래했습니다. 지정 초기화자를 사용하면 멤버의 이름을 지정하여 초기화하므로, 순서에 상관없이 필요한 멤버만 초기화할 수 있고 코드의 가독성이 향상됩니다.

간단한 예제

기존 방식의 초기화

struct Person {
    std::string name;
    int age;
    std::string address;
};

int main() {
    Person person1{"Alice", 30, "Seoul"};
    Person person2{"Bob", 25}; // address를 초기화하지 않음
    return 0;
}

위 코드에서 person2를 초기화할 때 address를 초기화하지 않으면 기본값이 아닌 빈 문자열로 초기화됩니다. 멤버의 순서를 기억해야 하며, 일부 멤버만 초기화하기 어렵습니다.

지정 초기화자를 사용한 개선

struct Person {
    std::string name;
    int age;
    std::string address;
};

int main() {
    Person person1{
        .name = "Alice",
        .age = 30,
        .address = "Seoul"
    };

    Person person2{
        .name = "Bob",
        .age = 25
        // address는 기본값으로 초기화
    };

    return 0;
}

지정 초기화자를 사용하면 멤버의 순서에 상관없이 원하는 멤버만 초기화할 수 있습니다.

지정 초기화자의 사용 방법

1. 구조체와 클래스에서 사용

struct Point {
    int x;
    int y;
    int z;
};

int main() {
    Point p1{.x = 1, .y = 2, .z = 3};
    Point p2{.z = 3, .x = 1}; // y는 기본값으로 초기화
    return 0;
}

클래스에서도 동일하게 사용할 수 있습니다.

2. 중첩된 구조체 초기화

struct Address {
    std::string city;
    std::string street;
};

struct Person {
    std::string name;
    int age;
    Address address;
};

int main() {
    Person person{
        .name = "Charlie",
        .age = 28,
        .address = {
            .city = "Busan",
            .street = "Haeundae"
        }
    };
    return 0;
}

중첩된 구조체의 멤버도 지정 초기화자를 통해 초기화할 수 있습니다.

3. 배열 초기화

int arr[5] = {
    [0] = 10,
    [2] = 30,
    [4] = 50
};

// arr: {10, 0, 30, 0, 50}

배열의 특정 인덱스를 지정하여 초기화할 수 있습니다.

주의 사항

  • 비포드 선언된 멤버: 멤버의 이름을 사용하므로, 멤버가 미리 선언되어 있어야 합니다.
  • 상속된 멤버: 상속된 멤버에는 지정 초기화자를 사용할 수 없습니다.
  • 멤버 함수: 함수나 정적 멤버는 초기화할 수 없습니다.

지정 초기화자의 장점

  • 가독성 향상: 초기화하려는 멤버를 명시적으로 나타내어 코드의 이해가 쉽습니다.
  • 유연한 초기화: 멤버의 순서에 구애받지 않고 필요한 멤버만 초기화할 수 있습니다.
  • 유지 보수성 증가: 멤버의 추가나 순서 변경 시에도 초기화 코드의 수정이 최소화됩니다.

비교: 기존 초기화 방식과 지정 초기화자

초기화 방식 장점 단점

위치 기반 초기화 간단하고 짧은 코드 멤버 순서에 의존, 멤버 추가 시 문제 발생
지정 초기화자 명확한 멤버 지정, 순서에 무관 코드가 길어질 수 있음

결론

C++20의 지정 초기화자를 사용하면 구조체와 클래스의 멤버를 더욱 명확하고 유연하게 초기화할 수 있습니다. 이는 코드의 가독성을 높이고, 유지 보수를 용이하게 만들어 줍니다.

 

참고 자료:

반응형