중괄호 초기화

특히 비교적 간단한 생성자에 대한 class생성자를 항상 정의할 필요는 없습니다. 사용자는 다음 예제와 같이 균일한 초기화를 사용하거나 struct 개체를 초기화 class 할 수 있습니다.

// no_constructor.cpp
// Compile with: cl /EHsc no_constructor.cpp
#include <time.h>

// No constructor
struct TempData
{
    int StationId;
    time_t timeSet;
    double current;
    double maxTemp;
    double minTemp;
};

// Has a constructor
struct TempData2
{
    TempData2(double minimum, double maximum, double cur, int id, time_t t) :
       stationId{id}, timeSet{t}, current{cur}, maxTemp{maximum}, minTemp{minimum} {}
    int stationId;
    time_t timeSet;
    double current;
    double maxTemp;
    double minTemp;
};

int main()
{
    time_t time_to_set;

    // Member initialization (in order of declaration):
    TempData td{ 45978, time(&time_to_set), 28.9, 37.0, 16.7 };

    // When there's no constructor, an empty brace initializer does
    // value initialization = {0,0,0,0,0}
    TempData td_emptyInit{};

    // Uninitialized = if used, emits warning C4700 uninitialized local variable
    TempData td_noInit;

    // Member declaration (in order of ctor parameters)
    TempData2 td2{ 16.7, 37.0, 28.9, 45978, time(&time_to_set) };

    return 0;
}

class 생성자가 있거나 struct 없는 경우 멤버가 에 선언되는 class순서대로 목록 요소를 제공합니다. class 생성자가 있는 경우 매개 변수 순서대로 요소를 제공합니다. 형식에 암시적으로 또는 명시적으로 선언된 기본 생성자가 있는 경우 중괄호 초기화를 빈 중괄호와 함께 사용하여 호출할 수 있습니다. 예를 들어 빈 중괄호 초기화와 비어있지 않은 중괄호 초기화를 모두 사용하여 다음 class 을 초기화할 수 있습니다.

#include <string>
using namespace std;

class class_a {
public:
    class_a() {}
    class_a(string str) : m_string{ str } {}
    class_a(string str, double dbl) : m_string{ str }, m_double{ dbl } {}
double m_double;
string m_string;
};

int main()
{
    class_a c1{};
    class_a c1_1;

    class_a c2{ "ww" };
    class_a c2_1("xx");

    // order of parameters is the same as the constructor
    class_a c3{ "yy", 4.4 };
    class_a c3_1("zz", 5.5);
}

클래스에 기본값이 아닌 생성자가 있는 경우 클래스 멤버가 중괄호 이니셜라이저에 나타나는 순서는 해당 매개 변수가 생성자에 나타나는 순서이며, 멤버가 선언되는 순서는 아닙니다(이전 예제와 class_a 같이). 그렇지 않으면 형식에 선언된 생성자가 없으면 멤버 이니셜라이저가 선언된 순서와 동일한 순서로 중괄호 이니셜라이저에 표시되어야 합니다. 이 경우 원하는 만큼 공용 멤버를 초기화할 수 있지만 멤버를 건너뛸 수는 없습니다. 다음 예제에서는 선언된 생성자가 없을 때 중괄호 초기화에 사용되는 순서를 보여줍니다.

class class_d {
public:
    float m_float;
    string m_string;
    wchar_t m_char;
};

int main()
{
    class_d d1{};
    class_d d1{ 4.5 };
    class_d d2{ 4.5, "string" };
    class_d d3{ 4.5, "string", 'c' };

    class_d d4{ "string", 'c' }; // compiler error
    class_d d5{ "string", 'c', 2.0 }; // compiler error
}

기본 생성자가 명시적으로 선언되었지만 삭제된 것으로 표시된 경우 빈 중괄호 초기화를 사용할 수 없습니다.

class class_f {
public:
    class_f() = delete;
    class_f(string x): m_string { x } {}
    string m_string;
};
int main()
{
    class_f cf{ "hello" };
    class_f cf1{}; // compiler error C2280: attempting to reference a deleted function
}

일반적으로 초기화를 수행하는 모든 위치에서 중괄호 초기화를 사용할 수 있습니다(예: 함수 매개 변수 또는 반환 값으로 또는 키워드(keyword) 사용 new ).

class_d* cf = new class_d{4.5};
kr->add_d({ 4.5 });
return { 4.5 };

모드 이상에서는 /std:c++17 빈 중괄호 초기화에 대한 규칙이 약간 더 제한적입니다. 파생 생성자 및 확장 집계 초기화를 참조 하세요.

initializer_list 생성자

initializer_list 클래스생성자 및 다른 컨텍스트에서 사용할 수 있는 지정된 형식의 개체 목록을 나타냅니다. 중괄호 초기화를 사용하여 initializer_list 생성할 수 있습니다.

initializer_list<int> int_list{5, 6, 7};

Important

이 클래스를 사용하려면 initializer_list> 헤더를 <포함해야 합니다.

복사 initializer_list 할 수 있습니다. 이 경우 새 목록의 멤버는 원래 목록의 멤버에 대한 참조입니다.

initializer_list<int> ilist1{ 5, 6, 7 };
initializer_list<int> ilist2( ilist1 );
if (ilist1.begin() == ilist2.begin())
    cout << "yes" << endl; // expect "yes"

표준 라이브러리 컨테이너 클래스 및 stringwstringregex또한 생성자가 있습니다.initializer_list 다음 예제에서는 이러한 생성자를 사용하여 중괄호 초기화를 수행하는 방법을 보여 줍니다.

vector<int> v1{ 9, 10, 11 };
map<int, string> m1{ {1, "a"}, {2, "b"} };
string s{ 'a', 'b', 'c' };
regex rgx{ 'x', 'y', 'z' };

참고 항목

클래스 및 구조체
생성자