Bonjour à tous!
Je retrouve dans un code en C++ que j'ai créé/écrit(!) ce code:
:oops:Code:
1
2
3
4
5
6
7 string anac="2013"; //Pourquoi écrire string CC(anac); //plutôt que: string CC=anac; //?
Merci pour une réponse.
Version imprimable
Bonjour à tous!
Je retrouve dans un code en C++ que j'ai créé/écrit(!) ce code:
:oops:Code:
1
2
3
4
5
6
7 string anac="2013"; //Pourquoi écrire string CC(anac); //plutôt que: string CC=anac; //?
Merci pour une réponse.
Salut,
Tout simplement parce que, hors toute optimisation de la part du compilateur, string CC(anac); va directement appeler le constructeur par copie, alors que string CC=anac; utilise l'opérateur d'affectation qui, classiquement
Tout cela prend, potentiellement, beaucoup de temps facilement gagné ;)
- crée une copie de l'objet (constructeur par copie !!)
- swape membre à membre les membres de l'objet d'origine et ceux de l'objet "copié"
- appel le destructeur pour l'objet copié (logique, vu qu'on quitte la portée dans laquelle il est défini)
La version parenthèse est un appel explicite au constructeur.
La version affecte est potentiellement différente, cela va dépendre (mais je ne sais plus exactement comment) de la présence de certaines méthodes:
- constructeur par défaut
- constructeur par copie
- operator=
le code string CC = anac; est équivalent à:
- la construction par défaut de CC ( appel de string() )
- l'affectation de anac à CC ( appel de string& operator=(const string&) )
ou à
- la construction par copie de CC via anac ( appel de string(const string&) )
et le code string CC = string("2013");peut être équivalent à
- la construction explicite d'un string temporaire avec l'argument "2013"
- la construction par défaut de CC
- l'affectation du temporaire à CC
- la destruction du temporaire
Ce peut aussi être
- la construction explicite d'un string temporaire avec l'argument "2013"
- la construction par copie de CC.
- la destruction du temporaire
Pour une string, c'est le constructeur par copie qui est appelé.
Mais pour certaines classes, le comportement peut être différent, surtout si le barbare de codeur a miné son code.
songe à ceci
PS: doublé... ca m'apprendra à vouloir faire des réponses longuesCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 struct A{ int a; A():valeur(0){}//constructeur par defaut A(const A& a):valeur(a.valeur){}//constructeur par copie A& operator=(int v){valeur=v+1; return *this;}//affectation } struct B{ int valeur; B():valeur(0){}//constructeur par defaut B(int v):valeur(v){}//constructeur de conversion B& operator=(const B& b){valeur=b.valeur+7; return *this;}//copie } int main(){ A a_def, a_explicit(0); A a_copie(a_explicit); A a_init = 1; A a_affect = a_explicit; B b_def, b_explicit(0); B b_copie(b_explicit); B b_init = 1; B b_affect = b_explicit; }
Salut,
Les 2 constructions sont équivalentes et correspondent à l'appel du constructeur de copie. En gros ce n'est pas du tout une optimisation du compilateur mais une construction prévue par la norme (copy-initialisation and direct-initialisation) :
alors que :Code:
1
2
3
4
5
6
7
8
9
10
11
12 struct A { private: A&operator=(A); }; int main() { A a1; A a2 = a1; // Ok return 0; }
Pour résumer :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 struct A { A(){} A&operator=(A const&) {return *this;} private: A(A const&); }; int main() { A a1; A a2 = a1; // error: 'A::A(const A&)' is private return 0; }
L'initialisation directe string CC(anac); et l'initialisation par copie string CC=anac; sont strictement équivalentes. A titre perso, je préfère la seconde, elle montre mieux (à mon avis) qu'il s'agit d'une copie.
[edit] l'optimisation c'est lorsque le constructeur par copie est remplacé par un autre constructeur dans les expression de type : TYPE variable = TYPE(p1,p2,...);. Ici, on devrait avoir un constructeur TYPE(p1,p2,...) appelé sur une variable temporaire puis le constructeur par copie TYPE(TYPE const&) sur la variable. L'optimisation consiste à appeler directement le constructeur TYPE(p1,p2,...) sur la variable. Mais le compilateur vérifie que le constructeur de copie est disponible avant de faire cette optimisation même s'il n'est ensuite pas appelé.
string CC(anac);
est donc plus rapide..?
plus concis
mais moins explicite selon d'autres
-----------
et string CC("2013");?:oops::oops:
non
entre string CC(anac); et string CC=anac;, ça va devenir assez difficile de parler de plus ou moins de consision (1 caractère en -...).
Juste un point de vue
Appel le constructeur dédié std::string(const char*,const Allocator& alloc = Allocator()) si je ne m'abuse.
merci à tous!
résolu!
+1 3DArchi
Voir le Guru Of the Week n° 36 : initialisation