11
votes

Comment utilisez-vous le constructeur non par défaut pour un membre?

J'ai deux classes xxx

Comment puis-je l'obtenir afin que ainstance est instancié avec a (int i) au lieu de essayer de rechercher un constructeur par défaut? Fondamentalement, je veux contrôler l'appel du constructeur A à partir du constructeur B .


1 commentaires

Je me rends compte que c'est un exemple, et pas le code réel, mais juste pour le fait de ~~ être un pédant ~~ qualité de code, il n'est généralement pas une bonne idée de faire des champs public . Bien sûr, il y a des cas d'utilisation, et ce n'est pas universellement mauvais, mais avant de le faire, assurez-vous qu'il y a une raison au-delà ", il pourrait simplifier une partie de mon code" ("Cela simplifie-t-il beaucoup de ma Code "est une raison parfaitement acceptable, bien que)


5 Réponses :


23
votes

Vous devez appeler un (int) explicitement dans la liste Initializer Constructor: xxx

où 3 est la valeur initiale que vous souhaitez utiliser. Bien que cela puisse être n'importe quel int. Voir les commentaires pour les notes importantes sur commande et autres réserves.


5 commentaires

Merci beaucoup. Je pensais que c'était seulement pour appeler des constructeurs de classe parents.


Oui, vous pouvez également l'utiliser pour initialiser les membres.


Dans certains cas, vous devez initialiser les membres (références, par exemple), et c'est ainsi que vous le faites.


N'oubliez pas que les membres sont initialisés dans l'ordre de leur déclaration dans la classe, pas dans la liste d'initialistes.


@Mike: Oui, dans GCC (Mac, Linus) et selon la norme La liste d'initialistes doit être dans le même ordre que les membres sont déclarés. Le compilateur Microsoft n'applique pas (ou invaincez) si vous le faites dans un ordre différent, mais vous ne devriez pas compter sur ce comportement. En outre, en utilisant "Ceci" est dangereux car votre objet n'est pas encore complètement construit. Certains compilateurs avertiront si vous faites cela, d'autres ne le feront pas.



3
votes

Utiliser une liste d'initialisation:

b::b() : aInstance(1) {}


0 commentaires

0
votes

Utilisez simplement un constructeur qui est défini comme celui-ci:

class b {
public:
    b()
    : aInstance(5)
    {}
    a aInstance;
};


5 commentaires

Avec une variable de membre, cela ne fonctionnera que si la variable est un statique const , comme dans statique const int x (3);


En fait, je dois noter que je ne transmettant pas une constante au constructeur, mais un autre membre de b. Quand j'essaie de faire une aînance (c); Il interprète cela comme définition de la fonction.


@Jerry: et a un type intégral.


Désolé, mon mauvais, que pensais-je à ... Fixer l'exemple à utiliser une liste init.


@Roger: Oui, ça aussi, maintenant que vous en parlez. Merci.



-2
votes

Je pense que vous devriez utiliser un pointeur sur 'A' comme: xxx

de cette façon, vous aurez un comportement défini. Bien sûr, vous aurez besoin de libérer * AInstance dans le destructeur.


2 commentaires

L'allocation de tas n'est pas très préférable à la répartition des empiler. Votre code manque maintenant un constructeur de copie, un opérateur d'affectation et destructeur.


Je suis d'accord. J'étais un peu trop rapide avec mon commentaire, surtout depuis qu'Anstance n'est qu'un petit objet. Je pensais à des situations de vie réelle où des objets pourraient être plus gros, où vous pourriez avoir une initialisation paresseuse, etc. Je suppose que je faisais trop de C # et Java ces derniers temps où presque tout est fait par référence;)



0
votes

Les deux premières réponses ne fonctionneront pas. Vous mettez des déclarations de classe dans les fichiers d'en-tête .H et (membre) définitions de fonction dans les fichiers .cpp. Les bretelles {} que les répondants ont mis définir le bloc de constructeur B. En pratique, personne ne voudrait que ça vide. Pourtant, vous ne pouvez pas la définir correctement dans le fichier .CPP ou le compilateur signalera une erreur de «redéfinition». (Lorsque le lieneur serait de toute façon si le fichier d'en-tête est compris dans plusieurs unités de traduction), car le but des fichiers d'en-tête est qu'ils peuvent être inclus dans plusieurs .CPP. Les réponses ci-dessus sont inexactées.


0 commentaires