Sdílet prostřednictvím


Inicializace složenými závorkami

Není vždy nutné definovat konstruktor pro class, zejména ty, které jsou relativně jednoduché. Uživatelé mohou inicializovat objekty objekty nebo class struct pomocí jednotné inicializace, jak je znázorněno v následujícím příkladu:

// 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;
}

Pokud konstruktor class nebo struct nemá, zadáte prvky seznamu v pořadí, v jakém jsou členy deklarovány v classsouboru . class Pokud má konstruktor, zadejte prvky v pořadí parametrů. Pokud má typ výchozí konstruktor, implicitně nebo explicitně deklarovaný, můžete k jeho vyvolání použít inicializaci složené závorky s prázdnými složenými závorkami. Například následující class můžou být inicializovány pomocí prázdné i neprázdné inicializace závorek:

#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);
}

Pokud má třída jiné než výchozí konstruktory, pořadí, ve kterém se členy třídy objeví v inicializátoru závorek, je pořadí, ve kterém se odpovídající parametry zobrazují v konstruktoru, nikoli pořadí, ve kterém jsou členy deklarovány (stejně jako class_a v předchozím příkladu). Pokud typ nemá žádný deklarovaný konstruktor, musí se inicializátory členů objevit v inicializátoru složené závorky ve stejném pořadí, v jakém jsou deklarovány. V tomto případě můžete inicializovat tolik veřejných členů, kolik chcete, ale nemůžete přeskočit žádného člena. Následující příklad ukazuje pořadí použité při inicializaci závorek, pokud neexistuje žádný deklarovaný konstruktor:

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
}

Pokud je výchozí konstruktor explicitně deklarován, ale označený jako odstraněný, nelze použít inicializaci prázdných závorek:

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
}

Inicializaci závorek můžete použít kdekoli, kde byste obvykle dělali inicializaci – například jako parametr funkce nebo návratovou hodnotu nebo s klíčovým slovem new :

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

V /std:c++17 režimu a později jsou pravidla pro inicializaci prázdných závorek o něco přísnější. Viz odvozené konstruktory a rozšířené inicializace agregace.

konstruktory initializer_list

Třída initializer_list představuje seznam objektů zadaného typu, které lze použít v konstruktoru a v jiných kontextech. Initializer_list můžete vytvořit pomocí inicializace závorek:

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

Důležité

Chcete-li použít tuto třídu, musíte zahrnout hlavičku <initializer_list> .

Lze initializer_list zkopírovat. V tomto případě jsou členy nového seznamu odkazy na členy původního seznamu:

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

Standardní třídy kontejneru knihovny, a také string, wstringa regex, mají initializer_list konstruktory. Následující příklady ukazují, jak provést inicializaci závorek pomocí těchto konstruktorů:

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

Viz také

Třídy a struktury
Konstruktory