J'ai souvent vu que les gens créent des objets en C ++ en utilisant
Thing myThing("asdf");
Au lieu de cela:
Thing myThing = Thing("asdf");
Cela semble fonctionner (en utilisant gcc), du moins tant qu'il n'y a pas de modèles impliqués. Ma question maintenant, est-ce que la première ligne est correcte et si oui, dois-je l'utiliser?
Réponses:
Les deux lignes sont en fait correctes mais font des choses subtilement différentes.
La première ligne crée un nouvel objet sur la pile en appelant un constructeur du format
Thing(const char*)
.Le second est un peu plus complexe. Il fait essentiellement ce qui suit
Thing
à l'aide du constructeurThing(const char*)
Thing
à l'aide du constructeurThing(const Thing&)
~Thing()
l'objet créé à l'étape 1la source
Thing myThing = Thing(...)
n'utilise pas l'opérateur d'affectation, il est toujours construit par copie comme le direThing myThing(Thing(...))
, et n'implique pas de construction par défautThing
(modifier: le message a été corrigé par la suite)Je suppose qu'avec la deuxième ligne, vous voulez dire:
qui serait la manière standard de créer de nouveaux objets dynamiques (nécessaires pour la liaison dynamique et le polymorphisme) et de stocker leur adresse dans un pointeur. Votre code fait ce que JaredPar a décrit, à savoir créer deux objets (l'un a passé a
const char*
, l'autre a passé aconst Thing&
), puis appeler le destructeur (~Thing()
) sur le premier objet (const char*
celui).En revanche, ceci:
crée un objet statique qui est détruit automatiquement à la sortie de la portée actuelle.
la source
Le compilateur peut très bien optimiser la deuxième forme dans la première forme, mais ce n'est pas obligatoire.
Sortie de gcc 4.4:
la source
Tout simplement, les deux lignes créent l'objet sur la pile, plutôt que sur le tas comme le fait «new». La deuxième ligne implique en fait un deuxième appel à un constructeur de copie, donc cela doit être évité (il doit également être corrigé comme indiqué dans les commentaires). Vous devriez utiliser la pile pour les petits objets autant que possible car elle est plus rapide, mais si vos objets vont survivre plus longtemps que le cadre de la pile, alors c'est clairement le mauvais choix.
la source
Idéalement, un compilateur optimiserait le second, mais ce n'est pas obligatoire. Le premier est le meilleur moyen. Cependant, il est assez critique de comprendre la distinction entre pile et tas en C ++, sine vous devez gérer votre propre mémoire de tas.
la source
J'ai joué un peu avec et la syntaxe semble devenir assez étrange lorsqu'un constructeur ne prend aucun argument. Laissez-moi vous donner un exemple:
donc juste écrire Thing myThing sans crochets appelle le constructeur, tandis que Thing myThing () fait du compilateur ce que vous voulez créer un pointeur de fonction ou quelque chose ?? !!
la source
En annexe à JaredPar réponse
1-ctor habituel, 2nd-function-like-ctor avec un objet temporaire.
Compilez cette source quelque part ici http://melpon.org/wandbox/ avec différents compilateurs
Et vous verrez le résultat.
D'après ISO / CEI 14882 2003-10-15
Votre 1ère, 2ème construction s'appelle l'initialisation directe
Où lire sur RVO:
Désactivez-le avec l'indicateur du compilateur du commentaire pour afficher un tel comportement de copie)
la source