Bonjour à tous,
je me demande comment je peux utiliser une liste d'initialisation avec plusieurs membres. Ma classe en possède plusieurs, et la FAQ ne montre un exemple qu'avec un seul...
Merci !
Bonjour à tous,
je me demande comment je peux utiliser une liste d'initialisation avec plusieurs membres. Ma classe en possède plusieurs, et la FAQ ne montre un exemple qu'avec un seul...
Merci !
Mindiell
"Souvent, femme barrit" - Elephant man
Avec une virgule .
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 A::A(T t,TT tt,TTT ttt):truc(t), titi(tt), toto(ttt) { }
"Never use brute force in fighting an exponential." (Andrei Alexandrescu)
Mes articles dont Conseils divers sur le C++
Une très bonne doc sur le C++ (en) Why linux is better (fr)
Salut,
Tu les mets, tout simplement, l'un après l'autre, séparés par une virgule
La seule chose à laquelle il faille faire attention, c'est de les mettre dans l'ordre dans lequel ils sont déclarés dans la classe
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Ouaip...
La preuve: si tu compile
tu auras un avertissement "a est initialisé apres f"...(enfin, avec les bons réglages du compilateur )
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 class Maclass { public: Maclass(int a, float f):a(a),f(f){} ~Maclass(){} private: float f; int a; };
Cela n'a rien à voir avec l'ordre dans lequel sont fournis les arguments, mais c'est bel et bien l'ordre dans lequel sont déclarés, et donc construits, les membres en mémoire
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Voici le code utilisé :
Avec Visual C++ 8 et un avertissement niveau 4 (le max):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 class Maclass { public: Maclass(int a, float f):a(a),f(f){} ~Maclass(){} private: float f; int a; }; int main() { Maclass t(2, 5.9f); return 0; }
Pas d'avertissements du tout !------ Début de la génération : Projet : test_MT, Configuration : Release Win32 ------
Compilation en cours...
main.cpp
Édition des liens en cours...
Génération de code en cours
Fin de la génération du code
Incorporation du manifeste en cours...
Le journal de génération a été enregistré à l'emplacement "file://c:\Documents and Settings\Gwen\Bureau\test_MT\test_MT\Release\BuildLog.htm"
test_MT - 0 erreur(s), 0 avertissement(s)
========== Génération : 1 a réussi, 0 a échoué, 0 mis à jour, 0 a été ignoré ==========
Une petite précision quand même...
Tu peux ne pas faire ta liste dans l'ordre de déclaration des membres, cela n'empêchera pas de compiler.
Par contre, tu te payeras les frais
1- de la création sans savoir fournir les valeurs
2- de l'"initialisation" au moment où on passe sur la variable adéquate (et peut etre meme une belle copie ou ne assignation)
Si par contre, tu crées ta liste d'initialisation dans l'ordre dans lequel les membres sont déclarés, tu peux directement faire appel au constructeur adéquat, sans copie ni assignation par la suite... Du coup, tu gagne du temps
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Avec Codeblocks, il me signale bien ce souci...
Merci à vous en tout cas !
Mindiell
"Souvent, femme barrit" - Elephant man
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
OK, comment veux tu que je fasse des progrès si le compilo m'indique même pas les warnings adéquats?
Bon c'est clair que Visual outrepasse légèrement la norme !
En plus tu dis qu'il peut y avoir une recopie lors de l'appel? Ca craint pour la rapidité de mon code !
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Je veux pas dire de bétise... mais il me semble bien que la norme est très claire sur le sujet:
Soit, de toute maniere, quelque soit l'ordre dans la liste d'initialisation ca ne change pas...--Then, nonstatic data members shall be initialized in the order they
were declared in the class definition (again regardless of the order
of the mem-initializers).
Moi je dis que gcc devrait arrêter de fumer la moquette !
Par contre, il se peut que gcc affiche un warning (tout comme Visual d'ailleurs) si dans la liste d'initialisation, un constructeur utilise une variable déclarée APRES. Par exemple:
Pouff... warning... parceque l'initialisation se fait x, y, PUIS r ....
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 class Toto { int x; int y; int r; Toto(); }; Toto::Toto() : x(45), r(30), y(r) {}
Les compilateurs les plus "hard" mettront même un warning dès qu'un membre de la classe est utilisé comme paramètre d'initialisation. Ceci dit, le comportement dans ce cas est clairement indiqué comme "non-défini".
N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
Et surtout
Si Visual ne met pas de warning, c'est qu'il corrige tout seul le problème alors... Un tel compilateur ne peut pas se permettre des pertes de performances sans même en avertir l'utilisateur ! (dans ce cas au moins)
L'avertissement du compilo est juste pour nous prévenir qu'il va respecter l'ordre des déclarations des membres comme la norme lui demande.
Il n'est pas obligé de nous prévenir. C'est exactement pareil que les compilos qui signalent que 42 ne matchera pas un %s dans un printf.
Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...
Donc pas de recopie lors d'un appel ?
Visual est très mauvais en ce qui concerne les warnings. On l'a vu, même le 8 ne signale pas ce piège ("gotcha") pourtant courant, et en plus il ne possède aucun équivalent à -Wwrite-strings...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Je trouve au contraire que c'est une excellente chose que de prévenir du fait que quelque chose ne sera pas effectué de la manière dont la personne l'a codé, mais bel et bien de la manière dont la norme le suggère/précise...
Cela peut permettre au codeur de se rendre compte qu'il compte peut être un peu trop sur un effet de bord qui ne se présentera pas forcément, voire qu'il a suivi une mauvaise logique (une logique "illogique" ) et ne peut que l'inciter, s'il décide de prêter attention à ces avertissements, à coder des applications de meilleure qualité.
Rien n'est plus frustrant pour l'utilisateur de n'importe quelle application que de la voir "s'arrêter toute seule" parce que la (le groupe de) personne(s) qui l'a (l'ont) créé ont codé comme des cochons, et n'ont pas évité une erreur quelle qu'elle soit alors qu'il y avait moyen de l'éviter
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Mais c'est exactement ce que je dis: IL Y A un warning, quand c'est nécessaire !
Je viens de vérifier... VS2007 en tout cas met bien un warning dès que l'odre implique des effets de bord.
Si il n'y a aucun effet de bord, il n'y a pas de warning...
Je vais vérifier sous VS2005 dès que j'aurai le temps
Par exemple:
Ne met aucun warning...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 class A { int a; int b; int c; inline A(int p1, int p2) : c(p1), b(p2), a(0) {} };
Affiche un joli warning...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 class A { int a; int b; int c; inline A(int p1, int p2) : c(p1), b(p2), a(p1++) {} };
Je trouve ca tout à fait normal et cohérent avec la norme... Qui d'ailleurs, précise au passage comment l'initialisation doit être faite dans l'initialisation des membres non-statiques...
A noter que c'est exactement le même principe que pour l'initialisation des classes parentes:
Va commencer par initialiser C(2), PUIS B(0).... Les classes parentes étant initialisées dans l'ordre:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 class A : public C, B { inline A() : B(0), C(2) {} };
- classes virtuelles d'abord
- classes 'normales' dans l'ordre de profondeur, et de la déclaration (de gauche à droite donc).
- enfin les membres non-statiques dans l'ordre de leur déclaration.
Dans mon commentaire "hard", je voulais dire:
Si on suit la norme, ceci ne devrait pas mettre de warning... a étant correctement initialisé quand c l'est !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 class A { int a; int b; int c; inline A() : c(a++), b(4), a(2) {} };
Mais Visual affiche un warning dans ce cas là, SAUF si a est membre d'une classe parente. Ce qui est, à mon avis, TRES BIEN, car de toute manière c'est "laid" et surtout dangereux
N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
Et surtout
Pour etre sur que c'est clair, l'initialisation se fait dans l'ordre de declaration dans la classe (pourquoi? parce que la destruction se fait en sens inverse de construction et que le destructeur ne peut pas savoir -- sans cout supplementaire -- quel ordre a ete utilise, en particulier quand il y a plusieurs constructeurs) mais sans tes "frais".
La norme n'impose ni ne demande rien sur les warnings.Envoyé par nicroman
Au contraire de toi, meme si l'application de la regle n'entraine pas un comportement different, je prefere avoir un warning: la situation n'est pas propre.
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.
@nicroman
J'ai l'impression, à la lecture de ton raisonnement, que tu considère les avertissements comme des "empêcheurs de coder en rond"...
Il ne faut pas les voir ainsi:
Qu'il y ai ou non effet de bord, que ce soit dans une liste d'initialisation ou dans n'importe quelle autre situation dans laquelle on reçoit un avertissement du compilo, l'avertissement est là pour t'indiquer "attention, ton comportement est *potentiellement* dangereux/inutile/sans effet"...
Si un code est inutile/sans effet, cela signifie que tu alourdis inutilement ton code, et que tu peux supprimer un certain nombre de lignes... en gagnant en lisibilité.
Si un code est dangereux, et au moins tu es d'accord avec ca, c'est déjà pas si mal , cela signifie que tu es devant le précipice et que tu t'apprête à faire un grand pas en avant.
Que ce soit l'une ou l'autre des solutions, le fait de savoir que ta manière de coder ne sera pas prise en compte telle quelle ne peut qu'être bénéfique pour la qualité générale de ce que tu a codé...
Et comme le but d'un développeur reste, quand même, d'essayer de fournir les meilleures (ou en tout cas les moins mauvaises) applications possibles, je ne comprend pas vraiment pourquoi tu "râle" contre des avertissements que tu juges "inutiles"...
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager