Bonjour,
quelques questions :
1-quel est la signification de "explicit" ?
2-quel est l'intérêt de définir un constructeur "explicit" ?
3-Doit on déclarer systématiquement un constructeur "explicit"?
![]()
Bonjour,
quelques questions :
1-quel est la signification de "explicit" ?
2-quel est l'intérêt de définir un constructeur "explicit" ?
3-Doit on déclarer systématiquement un constructeur "explicit"?
![]()
Les constructeurs des pointeurs intelligents.
ouai je vais mettre mon nez dans les sources de boost![]()
Tu peux aussi regarder le auto_ptr de la STL (en-tête <memory>)
Je dirais que tu dois déclarer tes constructeurs explicit en règle générale, et ne le supprimer que sur les constructeurs qui impliquent une vraie conversion.
Exemple: Une classe de chaîne de caractères peut possèder un constructeur implicite sur char const* (conversion), mais un constructeur explicite sur size_t (où l'argument serait une taille).
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.
Salut,
Je viens un peu après la bataille, mais, dés qu'un constructeur prend un argument, il peut être considéré comme opérateur de conversion.
Ainsi, avec une classe proche de
si tu crées une fonction prenant un A en argument comme
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 class A { public: A(int i):i(i){} i leI() const{return i;} private: int i; };
il est tout à fait possible d'appeler foo en passant en argument... un entier, sous une forme proche de
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 void foo(A /* const & */ a) { std::cout<<a.leI()<<std::endl; }
car le constructeur prenant un entier de la classe A servira d'opérateur de conversion implicite du type entier vers le type A.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 int main() { int i = 123; foo(i); return 0; }
Dans l'exemple ci-dessus, ce n'est pas *forcément* embêtant, mais, dans d'autres, cela peut provoquer quelques soucis (imagine si le constructeur de la classe A venait à créer un tableau de 1000 entiers, par exemple)
Pour éviter ce phénomène de conversion implicite, il est possible de déclarer le constructeur explicite.
Cela va indiquer au compilateur de ne créer une classe A que si l'auteur du code le demande explicitement.
Ainsi, en modifiant tout juste la classe A précédente pour déclarer le constructeur explicite sous la forme de
le code précédent n'est plus valide, et, pour pouvoir appeler foo (qui reste inchangée), tu devra clairement dire au compilateur de créer un objet de type A au départ de ton entier, sous une forme proche de
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 class A { public: explicit A(int i):i(i){} i leI() const {return i;} private: int i; };
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 int main() { int i = 123; foo(A(i)); return 0; }
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
Un autre exemple ici, si tu comprends l'anglais.
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.
Partager