Comment sait-on si l'object est "un peu gros" à part faire un benchmark ?
Je vais plutôt répondre à : Quand passer un objet par référence constante plutôt que par valeur (recopie) ?
La réponse rapide : Si l'objet n'est pas modifié: tout le temps. Sinon, passage par adresse (pas par référence).
La réponse longue :
Un passage par référence coute la même chose qu'un passage par adresse : la copie de l’adresse de l'objet (4 octets en 32 bits, 8 en 64 bits). D'un point de vu mémoire, un objet faisant très souvent plus de 4 octets, il doit donc quasiment tout le temps être passé par référence.
De plus la recopie d'un objet (même petit) n'est pas obligatoirement gratuite. Le constructeur par recopie peut faire des opérations relativement longue. Un passage par référence évite la recopie.
Une recopie perd le "type réel" de l'objet et casse le polymorphisme:
Le cassage du polymorphisme peut être voulu, mais ça surprendra probablement l'utilisateur. Et je conseille un appelle explicite à la méthode d'origine si c'est voulu : "toto.Obj::getvalue()"
Par contre, je déconseille très fortement le passage par référence non constante:
À la lecture d'un code déjà écrit, impossible de savoir si l'objet sera modifié par la fonction sans aller voir la définition de celle-ci. Si une fonction modifie un argument, c'est passage par adresse. point. Au moins c'est clair (à la lecture) : je passe l'objet=>pas de modif, je passe l'adresse => modif.
Impossible de passer des objets temporaires. Ce code ne compile pas :
[^] # Re: Très rapide review
Posté par GaMa (site web personnel) . En réponse au journal Petit Framework de jeu 2d en C++. Évalué à 5.
Je vais plutôt répondre à : Quand passer un objet par référence constante plutôt que par valeur (recopie) ?
La réponse rapide : Si l'objet n'est pas modifié: tout le temps. Sinon, passage par adresse (pas par référence).
La réponse longue :
Un passage par référence coute la même chose qu'un passage par adresse : la copie de l’adresse de l'objet (4 octets en 32 bits, 8 en 64 bits). D'un point de vu mémoire, un objet faisant très souvent plus de 4 octets, il doit donc quasiment tout le temps être passé par référence.
De plus la recopie d'un objet (même petit) n'est pas obligatoirement gratuite. Le constructeur par recopie peut faire des opérations relativement longue. Un passage par référence évite la recopie.
Une recopie perd le "type réel" de l'objet et casse le polymorphisme:
Le cassage du polymorphisme peut être voulu, mais ça surprendra probablement l'utilisateur. Et je conseille un appelle explicite à la méthode d'origine si c'est voulu : "toto.Obj::getvalue()"
Par contre, je déconseille très fortement le passage par référence non constante:
Avec "void test(const Obj& toto)" ça compile.
Matthieu Gautier|irc:starmad