Initialisation de l’accolade

Il n’est pas toujours nécessaire de définir un constructeur pour un class, en particulier ceux qui sont relativement simples. Les utilisateurs peuvent initialiser des objets d’un class ou struct à l’aide d’une initialisation uniforme, comme illustré dans l’exemple suivant :

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

Lorsqu’un class constructeur ou struct n’a pas de constructeur, vous fournissez les éléments de liste dans l’ordre dans lequel les membres sont déclarés dans le class. Si le class constructeur a un constructeur, fournissez les éléments dans l’ordre des paramètres. Si un type a un constructeur par défaut, implicitement ou explicitement déclaré, vous pouvez utiliser l’initialisation d’accolades avec des accolades vides pour l’appeler. Par exemple, les éléments suivants class peuvent être initialisés à l’aide de l’initialisation d’accolades vides et non vides :

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

Si une classe a des constructeurs non par défaut, l’ordre dans lequel les membres de classe apparaissent dans l’initialiseur d’accolade est l’ordre dans lequel les paramètres correspondants apparaissent dans le constructeur, et non l’ordre dans lequel les membres sont déclarés (comme dans class_a l’exemple précédent). Sinon, si le type n’a pas de constructeur déclaré, les initialiseurs membres doivent apparaître dans l’initialiseur d’accolades dans le même ordre qu’ils sont déclarés. Dans ce cas, vous pouvez initialiser autant de membres publics que vous le souhaitez, mais vous ne pouvez ignorer aucun membre. L’exemple suivant montre l’ordre utilisé dans l’initialisation de l’accolade lorsqu’il n’existe aucun constructeur déclaré :

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
}

Si le constructeur par défaut est explicitement déclaré mais marqué comme supprimé, l’initialisation de l’accolade vide ne peut pas être utilisée :

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
}

Vous pouvez utiliser l’initialisation d’accolades partout où vous le feriez généralement , par exemple, en tant que paramètre de fonction ou valeur de retour, ou avec la new mot clé :

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

En /std:c++17 mode et ultérieurement, les règles d’initialisation d’accolades vides sont légèrement plus restrictives. Consultez les constructeurs dérivés et l’initialisation d’agrégation étendue.

constructeurs initializer_list

La classe initializer_list représente une liste d’objets d’un type spécifié qui peut être utilisé dans un constructeur et dans d’autres contextes. Vous pouvez construire un initializer_list à l’aide de l’initialisation de l’accolade :

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

Important

Pour utiliser cette classe, vous devez inclure l’en-tête <initializer_list> .

Une initializer_list copie peut être effectuée. Dans ce cas, les membres de la nouvelle liste sont des références aux membres de la liste d’origine :

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

Les classes de conteneur de bibliothèque standard, ainsi que string, wstringet , et regex, ont initializer_list des constructeurs. Les exemples suivants montrent comment effectuer une initialisation d’accolade avec ces constructeurs :

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

Voir aussi

Classes et structs
Constructeurs