Appel d'un constructeur de la classe de base à partir du corps du constructeur d'une sous-classe

j'avais l'impression que c'était impossible, voir par exemple: appelant le constructeur de la classe de base après quelques autres instructions en C++

Mais le programme suivant fonctionne et produit deux lignes de "constructeur personne":

#include <iostream>

class Person
{
public:
    Person() 
    { 
        std::cout << "Constructor Person" << std::endl; }
    };

class Child : public Person
{
public:
    Child() 
    { 
        c = 1; 
        Person(); 
    }
    int c;
};

int main() 
{
    Child child;
    return 0;
}

Le premier est un appel implicite du constructeur par défaut, c'est clair. Ce qui sur le 2ème - t-il dire que l'action décrite dans le titre est-il légitime? Je utilisez Visual C++ 2010.

8
demandé sur Community 2014-01-28 05:52:33

3 réponses

l'appel à l'intérieur du constructeur de classe enfant n'appelle pas le constructeur de classe de base, il crée un objet temporaire, sans nom et nouveau de type personne. Il sera détruit à la sortie du constructeur. Pour clarifier, votre exemple est le même que faire ceci:

Child() { c = 1; Person tempPerson; }

sauf dans ce cas, l'objet temporaire a un nom.

vous pouvez voir ce que je veux dire si vous modifiez un peu votre exemple:

class Person
{
public:
    Person(int id):id(id) { std::cout << "Constructor Person " << id << std::endl; }
    ~Person(){ std::cout << "Destroying Person " << id << std::endl; }
    int id;
};

class Child : public Person
{
public:
    Child():Person(1) { c = 1; Person(2); }
int c;
};

int main() {
Child child;

Person(3);
return 0;
}

This produit la sortie:

Constructor Person 1
Constructor Person 2
Destroying Person 2
Constructor Person 3
Destroying Person 3
Destroying Person 1
12
répondu zdan 2014-01-28 02:57:01

ce qui suit est un extrait de " Accelerated C++": "Les objets dérivés sont construits par:

1. Attribution de l'espace pour l'ensemble de l'objet (membres de la classe de base aussi bien que membres de la classe dérivée);

2. Appeler le constructeur de classe de base pour initialiser la partie de classe de base de l'objet;

3. Initialiser les membres de la classe dérivée comme indiqué par le constructeur initialiseur;

4. Exécuter le corps du constructeur de la classe dérivée, le cas échéant."

résumant les réponses et les commentaires: appeler un constructeur de la classe de base à partir du corps du constructeur d'une sous-classe est impossible dans le sens où le numéro 2 ci-dessus doit précéder le numéro 4. Mais nous pouvons encore créer un objet de base dans le corps du constructeur dérivé, appelant ainsi un constructeur de base. Ce sera un objet différent de l'objet construit avec le constructeur dérivé actuellement exécuté.

4
répondu TT_ 2014-01-28 21:25:47

vous ne pouvez pas l'appeler à partir du corps du constructeur enfant, mais vous pouvez le mettre dans la liste d'initialiseur:

public:
    Child() : Person() { c = 1; }

bien sûr, il n'est pas utile d'appeler le constructeur par défaut du parent car cela se produira automatiquement. Il est plus utile si vous avez besoin pour passer un paramètre au constructeur.

la raison pour laquelle vous ne pouvez pas appeler le constructeur à partir du corps est que C++ garantit que le parent sera terminé la construction avant le constructeur enfant démarre.

3
répondu Mark Ransom 2014-01-28 01:57:03