12
votes

Pourquoi ma sous-classe C ++ a-t-elle besoin d'un constructeur explicite?

J'ai une classe de base qui déclare et définit un constructeur, mais pour une raison quelconque, ma classe de dérivée publiquement ne voit pas ce constructeur, et je dois donc déclarer explicitement un constructeur de transfert dans la classe dérivée: xxx

dans le code ci-dessus, mon wirecount1 wirecount1 (100) La déclaration est rejetée par le compilateur ("Aucune fonction correspondante pour appeler 'wirecount1 :: wirecount1 (int)'"), tandis que mon wirecount0 et wirecount2 Les déclarations sont correctes.

Je ne suis pas sûr de comprendre pourquoi j'ai besoin de fournir le constructeur explicite présenté dans Wirecount2 . Est-ce parce que le compilateur génère un constructeur par défaut pour wirecount1 , et ce constructeur masque le constructeur wirecount0

pour référence, le compilateur est I686-Apple-Darwin10-GCC-4.2.1 (GCC) 4.2.1 (Apple Inc. Build 5659) .


0 commentaires

3 Réponses :


15
votes

Les constructeurs ne sont pas hérités. Vous devez créer un constructeur pour la classe dérivée. Le constructeur de la classe dérivée, de plus, doit appeler le constructeur de la classe de base.


4 commentaires

De plus, si la classe de base a un constructeur par défaut, le compilateur utilisera celui-ci si vous ne spécifiez pas explicitement un constructeur dans la liste d'initialistes d'un constructeur dans la classe dérivée.


Merci. Je n'ai pas réalisé que les constructeurs n'ont jamais été hérités. Je m'étais convaincu que d'autres constructeurs de classe de base (dans le code réel) étaient en fait visibles, mais j'attribue maintenant que à un tas de casting que le compilateur ait pu faire.


Je regrette qu'en tant que débutant, je n'ai pas encore assez de points de réputation pour résoudre votre réponse.


Je pensais pouvoir rentrer à la maison tôt ... maintenant je dois travailler des heures supplémentaires, remplissant exactement les mêmes lignes de code dans mes sous-classes.



9
votes

Toutes les classes dérivées doivent appeler le constructeur de leur classe de base sous une forme ou une forme.

Lorsque vous créez un constructeur surchargé, votre constructeur sans paramètre généré par défaut disparaît et les classes dérivées doivent appeler le constructeur surchargé. P>

Lorsque vous avez quelque chose comme ceci: p>

class Class0 {
public:
  Class0(int param){}
}

class Class1 : public Class0 {
}


5 commentaires

Je pense que vous avez mal interprété sa question. Il ne demande pas pourquoi il ne peut pas appeler le constructeur par défaut de Class1, mais pourquoi il n'y a pas de constructeur de classe1 (int) à appeler.


Le compilateur génère toujours un constructeur class1 () dans votre dernier exemple. C'est juste que ce constructeur est mal formé s'il est défini en fait (par défaut comme pour toutes les fonctions spéciales, il n'est déclaré que jusqu'à ce qu'il soit réellement utilisé). Vous pouvez vérifier cela en faisant un ami: classe classe2 {ami classe1 :: classe1 (); }; , qui fonctionne parce que le compilateur déclare implicitement le constructeur par défaut, que cela puisse être appelé.


Merci. Cela me rend très clair pour moi. Bien que j'apprécie la réponse de Shirik, je crois que votre exemple montre exactement ce qui se passe dans mon code.


@Johannes Schaub - Litb Merci pour cela, je ne le savais pas.


Theres une discussion à ce sujet à Stackoverflow.com/Questtions/22951260/... , FYI



1
votes

Vous devez construire votre classe de base avant de traiter avec dérivé. Si vous construisez votre classe dérivée avec des constructeurs non triviaux, le compilateur ne peut pas décider de quoi faire appel à la base, c'est pourquoi l'erreur se produit.


0 commentaires