Question

Dans un projet, je maintiens, je vois beaucoup de code comme ceci pour des méthodes simples get / set

const int & MyClass::getFoo() { return m_foo; }

void MyClass::setFoo(const int & foo) { m_foo = foo; }

Quel est le point à le faire au lieu de ce qui suit?

int MyClass::getFoo() { return m_foo; }  // Removed 'const' and '&' 

void MyClass::setFoo(const int foo) { m_foo = foo; }  // Removed '&'

Le passage d'une référence à un type primitif devrait exiger la même (ou plus) effort en se faisant passer la valeur du type, droit?
Il est juste un numéro après tout ...
Est-ce juste une micro-optimisation tentative ou est-il un véritable avantage?

Était-ce utile?

La solution

La différence est que si vous obtenez ce résultat en une référence vous, vous pouvez suivre les changements de la variable membre entier dans votre propre nom de variable sans rappeler la fonction.

const &int x = myObject.getFoo();
cout<<x<<endl;
//...
cout<<x<<endl;//x might have changed

Il est sans doute pas le meilleur choix de conception, et il est très dangereux de retourner une référence (const ou non), dans le cas où une variable qui obtient libéré du champ d'application est renvoyée. Donc, si vous retournez une référence, faites attention pour être sûr qu'il n'est pas une variable qui est hors de portée.

Il y a une légère différence pour le modificateur aussi, mais encore une fois sans doute pas quelque chose qui vaut la peine ou qui était prévu.

void test1(int x)
{
  cout<<x<<endl;//prints 1
}

void test2(const int &x)
{
  cout<<x<<endl;//prints 1 or something else possibly, another thread could have changed x
}

int main(int argc, char**argv)
{
  int x = 1;
  test1(x);
  //...
  test2(x);
  return 0;
}

Ainsi, le résultat final est que vous obtenez des modifications même après que les paramètres sont passés.

Autres conseils

Pour moi, passer un référence const pour les primitives est une erreur. Soit vous devez modifier la valeur, et dans ce cas vous passez un référence non const , ou vous avez juste besoin d'accéder à la valeur et dans ce cas vous passez un const .

références Const ne doit être utilisé pour les classes complexes, lorsque des objets de copie pourrait être un problème de performance. Dans le cas des primitives, à moins que vous devez modifier la valeur de la variable que vous ne devriez pas passer un référence . La raison en est que références prendre plus de temps de calcul que non-références , car avec références , le programme doit rechercher dans une table pour trouver adresse de l'objet. Une fois ce temps consultation est plus courte que le temps de la copie, les références sont une amélioration.

En général, ints et adresses ont la même longueur d'octets dans les implémentations à faible niveau. Ainsi, le temps de la copie d'un int en tant que valeur de retour pour une fonction est équivalente à la durée de la copie d'un adresse . Mais dans le cas où un int est retourné, pas en place est effectuée de regard, donc augmente les performances.

La principale différence entre le retour d'une valeur et en retournant une référence const est que vous pouvez const_cast cette référence et modifier la valeur.

Il est un exemple de mauvaise conception et une tentative de créer un design intelligent où le design simple et concis serait plus que suffisant. Au lieu de simplement retourner une valeur l'auteur fait des lecteurs de code penser à ce que l'intention qu'il aurait pu avoir.

Il n'y a pas beaucoup d'avantages. Je l'ai vu dans le cadre ou macro généré accesseurs avant. Le code macro ne distingue pas entre les primitifs et les types non-POD et juste utilisé à travers le conseil d'administration const type& pour setters. Je doute que ce soit un problème d'efficacité ou d'un véritable malentendu; les chances sont c'est une question de cohérence.

Je pense que ce type de code est écrit qui ont mal compris le concept de références et de l'utiliser pour tout, y compris les types de données primitifs. J'ai aussi vu un code comme celui-ci et ne peut pas voir aucun avantage de le faire.

Il n'y a pas de point et de bénéficier, sauf

void MyClass::setFoo(const int foo)
void MyClass::setFoo(const int& foo)

vous ne serez pas en mesure de réutiliser la mise en œuvre « foo » variable dans « setFoo ». Et je crois que « int & » est juste parce que Guy juste se habituer à passer toutes choses par référence const et il n'y a rien de mal à cela.

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