본문 바로가기
C++/C++14

C++14 : 애그리게이트 멤버 초기화(Aggregate member initialization)

by 개발자J의일상 2022. 4. 15.
반응형

C++11에는 생성자가 멤버 자체를 초기화하지 않은 경우 클래스 범위에서 멤버에 적용할 표현식인 멤버 이니셜라이저가 추가되었다.

멤버 이니셜라이저가 있는 클래스를 명시적으로 제외하도록 집계 정의가 변경되었다. 

따라서 집계 초기화(aggregate initialization)를 사용할 수 없다.

 

C++14는 이러한 제한을 완하하여 이러한 타입에 대한 집계 초기화를 허용한다.

중괄호 초기화 목록이 해당 인수에 대한 값을 제공하지 않으면 멤버 이니셜라이저가 이를 처리한다.

 

데이터 멤버는 기본적으로 초기화되지 않는다.

 

일반 변수와 마찬가지로 데이터 멤버는 기본적으로 초기화 되지 않는다.

아래 구조체 예제를 살펴보자.

#include <iostream>

struct Employee
{
    int id; // note: no initializer here
    int age;
    double wage;
};

int main()
{
    Employee joe; // note: no initializer here either
    std::cout << joe.id;

    return 0;
}

이니셜라이저를 제공하지 않았기 때문에 joe가 인스턴스화되면 joe.id, joe.age, joe.wage가 모두 초기화 되지 않는다.

그러면 joe.id 값을 출력하려고 할 때 정의되지 않은 동작이 발생한다.

 

집계(aggregate)란 무엇인가?

일반 프로그래밍에서 집계 데이터 타입(집계라고도 함)은 여러 데이터 멤버를 포함할 수 있는 어떠한 타입이다.

일부 타입의 집계에서는 구성원이 다른 타입(예: 구조체)을 가질 수 있지만, 다른 타입은 모든 구성원이 단일 타입(예: 배열)이어야 함을 요구한다.

 

C++에서 집계의 정의는 더 좁고 상당히 복잡하다.

 

C++ 집계의 정확한 정의는 제쳐두고, 이 시점에서 이해해야 할 중요한 점은 데이터 멤버만 있는 구조체(이 단원에서 생성할 유일한 종류의 구조체)가 집계라는 것이다. 배열도 역시 집계이다.

 

구조체의 집계 초기화

일반 변수는 단일 값만 보유할 수 있으므로 단일 이니셜라이저만 제공하면 된다.

int x { 5 }

그러나 구조체는 여러 멤버를 가질 수 있다.

struct Employee
{
    int id {};
    int age {};
    double wage {};
};

구조체 유형으로 객체를 정의할 때 초기화 시간에 여러 멤버를 초기화하는 방법이 필요하다.

Employee joe; // how do we initialize joe.id, joe.age, and joe.wage?

집계는 집계 초기화라는 초기화 형식을 사용하여 집계 멤버를 직접 초기화 할 수 있다.

이를 위해 쉼표로 구분된 초기화 값들인 초기화 목록을 초기화 방법으로 제공한다.

 

일반 변수가 복사 초기화, 직접 초기화, 목록 초기화가 될 수 있는 것처럼 집계 초기화에는 3가지 방법이 있다.

struct Employee
{
    int id {};
    int age {};
    double wage {};
};

int main()
{
    Employee frank = { 1, 32, 60000.0 }; // copy-list initialization using braced list
    Employee robert ( 3, 45, 62500.0 );  // direct initialization using parenthesized list (C++20)
    Employee joe { 2, 28, 45000.0 };     // list initialization using braced list (preferred)

    return 0;
}

이러한 각 초기화 방법은 멤버별 초기화를 수행한다. 즉, 구조체의 각 멤버는 선언 순서대로 초기화된다.

따라서 직원 joe { 2, 28, 45000.0 }; 먼저 joe.id를 값 2로 초기화 한 다음 joe.age를 값 28로 초기화 하고 joe.wage를 값 45000.0으로 초기화 한다. 

 

세번째 braced list 방식을 가장 추천한다.

 

https://en.wikipedia.org/wiki/C%2B%2B14#cite_note-9
https://www.learncpp.com/cpp-tutorial/struct-aggregate-initialization/
300x250

댓글