Quelle est la différence entre l'utilisation de listes d'initialisation pour initialiser des champs et les initialiser à l'intérieur du constructeur ?

Quelle est la différence entre l'utilisation de listes d'initialisation pour initialiser des champs et les initialiser à l'intérieur du constructeur ?


Sur certains tutoriels (par exemple http://www.tutorialspoint.com/cplusplus/cpp_constructor_destructor.htm) j'ai lu que les deux codes suivants sont équivalents.


Premier code :


class MyClass1{
public:
int a;
int b;
MyClass1(int a, int b) : a(a), b(b) {};
};

Deuxième code :


class MyClass2{
public:
int a;
int b;
MyClass2(int, int);
};
MyClass2::MyClass2(int a, int b){
this->a = a;
this->b = b;
}

En fait, ils me donnent les mêmes résultats. Mais, si j'utilise const membres, je ne suis plus capable de compiler le code.


class MyClass1{
public:
const int a;
const int b;
MyClass1(int a, int b) : a(a), b(b) {};
};
class MyClass2{
public:
const int a;
const int b;
MyClass2(int, int);
};
MyClass2::MyClass2(int a, int b){
this->a = a;
this->b = b;
}

En fait la première classe ne me donne pas d'erreur mais dans la deuxième classe il y a un assignment of read-only member . Donc, voici les questions :


Quelle est la vraie différence entre les deux méthodes d'initialisation ?


Utilise les listes d'initialisation comme seule méthode pour initialiser const membres d'une classe ?


Remarque :J'ai lu en ligne l'utilisation de constructeurs délégués pour éviter ce problème, mais leur utilisation n'est pas claire pour moi et ce qu'ils font réellement.


Réponses :


Une façon simple de voir les choses est de faire des liens avec des variables locales :



  1. L'utilisation de listes d'initialiseurs équivaut à cette vue des variables locales :


    int a = 1;
    int b = 2;

  2. La deuxième forme, les assignant à l'intérieur du constructeur est équivalente à ceci :


    int a;
    int b;
    a = 1;
    b = 2;


Vous pouvez voir comment cela peut être un problème avec const ou avec des objets qui n'ont pas de constructeur par défaut :


Membres de la const



  1. D'accord :


    const int a = 1;
    const int b = 2;

  2. Pas d'accord :


    const int a;
    const int b;
    a = 1;
    b = 2;


Types avec constructeur par défaut supprimé ou non accessible


par exemple :


class X {
public:
X() = delete; // default constructor deleted
X(int){}; // constructor with an int parameter
};


  1. D'accord :


    X x(1);

  2. Pas d'accord :


    X x;
    x = X(1);


3e option :initialiseurs de membres dans la classe (depuis c++11)


class A {
public:
const int a = 10;
};

Quelques réponses de code


class MyClass1{
public:
int a;
int b;
MyClass1(int a, int b) : a(a), b(b) {};
};
class MyClass2{
public:
int a;
int b;
MyClass2(int, int);
};
MyClass2::MyClass2(int a, int b){
this->a = a;
this->b = b;
}
class MyClass1{
public:
const int a;
const int b;
MyClass1(int a, int b) : a(a), b(b) {};
};
class MyClass2{
public:
const int a;
const int b;
MyClass2(int, int);
};
MyClass2::MyClass2(int a, int b){
this->a = a;
this->b = b;
}
int a = 1;
int b = 2;
int a;
int b;
a = 1;
b = 2;
const int a = 1;
const int b = 2;
const int a;
const int b;
a = 1;
b = 2;
class X { public:    X() = delete;
// default constructor deleted X(int){};
// constructor with an int parameter };
X x(1);
X x;
x = X(1);
class A { public:    const int a = 10;
};