Pourquoi ne l'implicite constructeur de copie appelle la classe de base constructeur de copie et le constructeur de copie n'en a pas?
Envisager une hiérarchie de classe où A
est la classe de base et B
dérive de A
.
Si le constructeur de copie n'est pas défini dans B
, le compilateur va synthétiser un. Lorsqu'il est invoqué, ce constructeur de copie d'appel seront la classe de base constructeur de copie (même celui synthétisé un, si aucun n'a été fournie par l'utilisateur).
#include <iostream>
class A {
int a;
public:
A() {
std::cout << "A::Default constructor" << std::endl;
}
A(const A& rhs) {
std::cout << "A::Copy constructor" << std::endl;
}
};
class B : public A {
int b;
public:
B() {
std::cout << "B::Default constructor" << std::endl;
}
};
int main(int argc, const char *argv[])
{
std::cout << "Creating B" << std::endl;
B b1;
std::cout << "Creating B by copy" << std::endl;
B b2(b1);
return 0;
}
De sortie:
Creating B
A::Default constructor
B::Default constructor
Creating B by copy
A::Copy constructor
Si l'utilisateur définit son propre constructeur de copie dans B
, lorsqu'il est appelé, ce constructeur de copie d'appel seront la classe de base de constructeur par défaut, à moins qu'un appel à la classe de base constructeur de copie est explicitement présent (par exemple, dans la liste d'initialisation).
#include <iostream>
class A {
int a;
public:
A() {
std::cout << "A::Default constructor" << std::endl;
}
A(const A& rhs) {
std::cout << "A::Copy constructor" << std::endl;
}
};
class B : public A {
int b;
public:
B() {
std::cout << "B::Default constructor" << std::endl;
}
B(const B& rhs) {
std::cout << "B::Copy constructor" << std::endl;
}
};
int main(int argc, const char *argv[])
{
std::cout << "Creating B" << std::endl;
B b1;
std::cout << "Creating B by copy" << std::endl;
B b2(b1);
return 0;
}
De sortie:
Creating B
A::Default constructor
B::Default constructor
Creating B by copy
A::Default constructor
B::Copy constructor
Ma question est, pourquoi ne pas l'défini par l'utilisateur copie appel du constructeur de la classe de base constructeur de copie par défaut?
- Si c'était de cette façon par défaut, comment voulez-vous préciser le cas où vous ne voulez pas que cela se produise?
ParentClass()
dans la liste d'initialiseur. Ce serait encore assez incohérent et confus, je crois.- En effet, j'espérais qu'il en vient à la même conclusion lorsque l'on pense à ce sujet...
- Exactement ma première question ainsi.
- Parce que le comité de normalisation avait un choix et faites le choix le plus logique à mon avis (Si vous ne spécifiez pas comment appeler le constructeur de classe de base, alors vous devez dire celui par défaut (celui avec pas de paramètres) que vous avez spécifié n'a pas de paramètres).
- notez également la même logique s'applique à tous les membres ainsi que les classes de base.
- J'apprécie toutes les réponses et les commentaires, merci pour vos contributions. Le fait semble être que, par défaut, il est conforme à toujours appeler le constructeur par défaut, sauf si un autre est explicitement demandé. Qui semble parfait et propre à moi et je suis heureuse aussi (en tant que développeur) que l'implicite constructeur de copie appelle le constructeur de copie de la classe de base. Mais si "l'appel du constructeur par défaut de tout constructeur, comme un défaut" principe existe, alors l'implicite constructeur de copie constitue une (apprécié) exception à la règle!
- Votre question est une réponse la plus précise à ma question, j'ai trouvé ... le Péril de style.
Vous devez vous connecter pour publier un commentaire.
C'est juste la façon dont l'implicite constructeur de copie est défini (il ne serait pas logique d'appel par défaut). Dès que vous définissez un constructeur (copie ou autre) sa normale comportement automatique est d'appeler le défaut constructeur parent, de sorte qu'il serait incohérent de le changer pour un utilisateur spécifique définie par le constructeur.
Toutes les bases de l'enfant constructeurs appeler le parent constructeur par défaut. C'est la façon dont la norme est définie. Comme vous l'avez souligné, si vous vouliez le dériver de la classe B à Un appel du constructeur de copie, vous devez le demander explicitement
C'est parce que le compilateur ne peut pas savoir pour chaque constructeur qui constuctor de la mère doit être appelé et nous avons donc le constructeurs par défaut Pour tous les autres, vous devez explicitement état de mer.
De sortie:
All base child constructors call the parent default constructor.
... sauf pour l'implicite constructeur de copie :)!Simple (éventuellement banal) réponse est parce que vous n'avez pas le dire. Depuis que vous êtes à l'écriture de la dérivée constructeur de copie, vous contrôler complètement la façon dont il se comporte. L'absence de spécification d'un appel à la base et le compilateur génère le code d'initialisation de la classe de base en appelant les classes de base de constructeur par défaut.