Question

Je vouloir assurer que je comprends passer par valeur vs passe par référence correctement. En particulier, je regarde les versions préfixe / postfix de l'opérateur ++ incrément pour un objet.

Supposons que nous avons la X de classe suivante:

class X{
private:
    int i;
public:
 X(){i=0;}
 X& operator ++ (){ ++i; return *this; } //prefix increment

 X operator ++ (int unused){ //postfix increment
  X ret(*this);
  i++;
  return ret;
 }

 operator int(){ return i; } //int cast
};

D'abord, ai-je mis à exécution les opérateurs incrément préfixe / postfix correctement?

Deuxièmement, comment économe en mémoire est l'opérateur de Postfix, par rapport à l'opérateur de préfixe? Plus précisément le nombre de copies d'objets X sont créés lorsque chaque version de l'opérateur est utilisé?

Une explication exactement ce qui se passe avec retour par référence vs retour par valeur peut me aider à comprendre.


Edit: Par exemple, le code suivant ...

X a;
X b=a++;

... a et b sont maintenant des alias?

Était-ce utile?

La solution

Ceci est une mise en œuvre correcte. Il est typique qu'un opérateur de Postfix sera pire sur la performance parce que vous devez créer une autre copie avant de faire l'incrément (et c'est la raison pour laquelle j'ai pris l'habitude d'utiliser toujours un préfixe à moins que je besoin de quelque chose d'autre).

Avec le retour par référence, vous retournez une référence l valeur à l'objet en cours. Le compilateur généralement mettre en œuvre en retournant l'adresse de l'objet en cours. Cela signifie que le retour de l'objet est aussi simple que le retour d'un nombre.

Cependant, avec retour par valeur, une copie doit être fait. Cela signifie qu'il ya plus d'informations à copier lors du retour (au lieu d'une adresse) ainsi qu'un constructeur de copie à l'appel. C'est là votre perte de performance entre en jeu.

L'efficacité de vos regards de mise en œuvre sur pied d'égalité avec les implémentations typiques.

EDIT: En ce qui concerne votre addendum, non, ils ne sont pas des alias. Vous avez créé deux objets distincts. Lorsque vous revenez en valeur (et lorsque vous avez créé un nouvel objet à partir de l'opérateur incrément postfix) ce nouvel objet est placé dans un emplacement de mémoire distinct.

Cependant, dans le code suivant, a et b sont Alias:

 int a = 0;
 int& b = ++a;

b est une adresse qui fait référence à un.

Autres conseils

Il est plus idiomatiques appeler le préfixe incrément de l'objet lui-même dans l'incrément postfix:

X operator++(int)
{
    X copy(*this);
    ++*this;         // call the prefix increment
    return copy;
}

La logique de incrémenter un objet X est donc uniquement contenu dans la version préfixe.

Vos opérateurs sont correctement mis en œuvre.

Dans l'opérateur préfixe, aucune copie de X sont faites.

Dans l'opérateur postfix, une copie est faite pour ret, et potentiellement une autre copie est faite lors du retour de la fonction, mais tous les compilateurs élidera cette copie.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top