11
votes

Est (* i) .member moins efficace que i-> membre

avoir xxx pré>

suppose qu'aucun opérateur n'est surchargé. p>


plus efficace (le cas échéant)? p>

(* p) .name code> vs. strong> p-> nom code> p>

quelque part à l'arrière de ma tête, j'entends des cloches sonneries , que l'opérateur * code> Dréréférence peut créer une copie temporaire d'un objet; est-ce vrai? p>


Le fond de cette question sont des cas comme celui-ci: P>

Person& Person::someFunction(){
    ...
    return *this;
}


7 commentaires

À ce stade, vous devriez beaucoup plus vous inquiéter de la lisibilité, et étant donné que -> est le sucre syntaxique plus courant, (* i) .m est fronçonné dans de nombreux endroits. Seulement si un profilage indique qu'il pourrait y avoir un problème en rapport avec cela, vous devriez commencer à vous inquiéter de son efficacité.


Je m'attendrais à ce que le compilateur produise exactement le même résultat. Vous pouvez vous répondre vous-même, compiler les deux codes à assembler et vérifier le code produit.


J'ai posé cette question à cause de la Contexte J'ai décrit - de nombreux opérateurs de base renvoient généralement une référence à soi et je vois très souvent qu'ils revenaient * ce ;


* p est une valeur L (vous pouvez faire * p = quelque chose; ). Comment cela pourrait-il créer un objet temporaire?


@Angew bon point, je pensais à personne & p2 = * p; et la possibilité qu'ils ne font pas référence au même objet


@Kalamarobliwy Il n'y a pas de telles possibilités. L'opérateur Dréréférence du pointeur intégré * renvoie une valeur L désignant l'objet pointé sur (vous pouvez y penser comme une référence à celle-ci).


Quelques conteneurs comme Boost's fibonacci_heap avoir un manipul_type qui ne supporte même pas opérateur -> (probablement uniquement hors de l'oubli), donc si vous êtes extrêmement général, vous devrait probablement utiliser une déséroférence explicite. Je ne le recommande pas cependant.


4 Réponses :


9
votes

Il n'y a pas de différence. Même la norme dit que les deux sont équivalents, et s'il y a un compilateur qui ne génère pas le même binaire pour les deux versions, c'est un mauvais.


3 commentaires

La même chose pour les types intégrés et défini par l'utilisateur ??


@Kalamarobliwy en supposant une surcharge de l'opérateur, oui.


Et pour les pointeurs intelligents standard ( std :: unique_ptr , std :: partagé_ptr ), les opérateurs surchargés se comportent toujours de la même manière.



1
votes

Tout bon compilateur produira les mêmes résultats. Vous pouvez vous répondre vous-même, compiler les deux codes à assembler et vérifier le code produit.


0 commentaires

8
votes

Lorsque vous retournez une référence, c'est exactement la même chose que de repasser un pointeur, la sémantique du pointeur exclu em>.
Vous écrivez un tailleOf (vide *) code> élément, pas un Tailleof (votreclass) code>.

Ainsi, lorsque vous faites cela: P>

Person& Person::someFunction(){
    ...
    return *this;
}


2 commentaires

C'est un bon point sur la taille du retour. Pouvez-vous expliquer, qu'est-ce que * p est juste par lui-même alors? Le résultat est une personne et une personne, ou une personne constante et?


Vous obtenez un l-valse , qui fait référence à l'adresse de l'objet, si je lisais Stackoverflow.com/questions/11347111/... correctement et selon Wikipedia: en.wikipedia.org/wiki/value_ (Computer_Science)



2
votes

Oui, il est beaucoup plus difficile de lire et de taper, de sorte que vous êtes beaucoup mieux à utiliser le x-> y que (* x) .y - mais autre que Efficacité de taper, il n'y a absolument aucune différence. Le compilateur doit toujours lire la valeur de x puis ajouter le décalage à y , que vous utilisiez un formulaire ou l'autre [en supposant qu'il n'y a pas d'objets / classes amusants impliqués qui remplacent le opérateur -> et Opérateur * respectivement, bien sûr]

Il n'y a certainement aucun objet supplémentaire créé lorsque (* x) est référencé. La valeur du pointeur est chargée dans un registre dans le processeur [1]. C'est tout.

retourner une référence est généralement plus efficace, car elle renvoie un pointeur (déguisé) à l'objet, plutôt que de faire une copie de l'objet. Pour les objets plus gros que la taille d'un pointeur, c'est généralement une victoire.

[1] Oui, nous pouvons avoir un compilateur C ++ pour un processeur qui n'a pas de registres. Je connais d'au moins un processeur de Class-Xerox que j'ai vu dans environ 1984, qui n'a pas de registres, c'était un processeur LISP dédié, et il suffit d'une pile pour des objets LISP ... mais ils sont loin d'être communs dans le monde d'aujourd'hui. Si quelqu'un travaille sur un processeur qui n'a pas de registres, veuillez ne pas descendre ma réponse simplement parce que je ne couvre pas cette option. J'essaie de garder la réponse simple.


0 commentaires