c++ passer des arguments par référence et pointeur
En c++
class bar
{
int i;
char b;
float d;
};
void foo ( bar arg );
void foo ( bar &arg );
void foo ( bar *arg );
Ceci est un exemple de classe / structure et de fonctions
j'ai quelques Qs
- Quelle est la différence entre la 1ère et la 2ème façon de passer l'argument dans 'asm', size, speed ?
- comment les arguments sont passés aux fonctions foo dans chaque cas ( en cas de pointeur je sais que le pointeur est placé sur la pile )
- lors du passage d'arguments, en termes d'efficacité à ( vitesse, taille, préférabilité ) Quel est le meilleur ?
- qu'est-ce que l'intel 'asm' syntaxe qui correspond à chacune des façons de passer des arguments ?
Je sais ce que la plupart disent de "cela n'a pas d'importance sur les compilateurs et les processeurs modernes" mais que se passe-t-il si nous parlons d'anciens processeurs ou compilateurs?
Merci d'avance
4 réponses
Le pointeur et les méthodes de référence doivent être assez comparables (à la fois en vitesse, en utilisation de la mémoire et en code généré).
Le Passage d'une classe force directement le compilateur à dupliquer la mémoire et à placer une copie de l'objet bar
sur la pile. Ce qui est pire, en C++, il y a toutes sortes de bits désagréables (le constructeur de copie par défaut et autres joyaux) associés à cela.
En C, j'utilise toujours (éventuellement const) des pointeurs. En C++, vous devriez probablement utiliser des références.
De toute manière raisonnable, le passage par référence entraînera probablement un code impliquant des adresses d'objets. Cependant, le problème principal est que l'utilisation de références est plus idiomatique C++ et devrait être le style préféré; vous ne devriez vraiment pas voir beaucoup de pointeurs bruts dans votre propre code.
Notez également que le passage par valeur et par référence est fondamentalement différent dans le sens où le passage par référence permet à l'appelé de modifier l'argument. Si quoi que ce soit, vous devriez comparer f(bar)
avec f(const bar &)
.
Les pointeurs et les références diffèrent syntaxiquement, et sont généralement identiques dans l'exécution et la génération de code. Quant aux compilateurs plus anciens... Je connaissais un bug dans le compilateur dos Borland 3 C++: il mettait en cache une valeur int (passée par référence) dans un registre, la modifiait et ne changeait pas la valeur d'origine en mémoire. En passant par le pointeur, un code équivalent a fonctionné comme prévu.
Cependant, je ne pense pas qu'un compilateur moderne puisse faire des choses aussi étranges (et Borland 5 a résolu le problème)
Comme pour coder le style (en dehors des pointeurs contre le compromis smartpointers), j'utilise généralement des références si l'adresse ne peut pas être nulle par contrat de fonction, et utilise des pointeurs autrement.
Fonction foo peut modifier arg dans les cas 2 et 3. Dans les premiers cas, le compilateur pourrait optimiser la création de copie, il est donc très difficile de comparer l'utilisation du processeur et de la mémoire.