11
votes

Pourquoi puis-je exposer les membres privés lorsque je retourne une référence d'une fonction de membre public?

Dans l'extrait de code, je suis capable d'accéder à la variable de membre privé en dehors de la portée de la classe. Bien que cela ne soit jamais fait, pourquoi est-il autorisé dans ce cas? Est-ce une mauvaise pratique de recevoir une variable privée retournée par référence? XXX

et concernant cette méthode, qu'est-ce que le type de retour transmet? Et aussi, quand devrais-je avoir un type de retour de ce type? xxx

PS: Je suis désolé si la ligne d'objet est vague. Quelqu'un peut-il le changer au contenu pertinent ici. Merci.


0 commentaires

5 Réponses :


4
votes

Renvoyer des membres privés comme référence est parfaitement valide et le programmeur qui écrit une classe est responsable de choisir avec soin si cela devrait être autorisé. Ce lien donne un exemple lorsque cela peut être fait.


0 commentaires

2
votes

Ce code: xxx

signifie que la fonction renvoie une référence à un entier. Tout comme lors du passage d'une valeur par référence à une fonction, si la valeur de retour de Methodtwo est modifiée, la valeur que méthodtwo est retournée. Dans ce cas, champ de classe x .

Dans le code que vous avez écrit, cela signifie que vous laissez la variable privée x échapper à sa portée ( un champ de classe) et être transmis dans le monde extérieur. Ceci est certainement une mauvaise pratique (car x peut être modifié de manière à casser la classe foo , mais il est certainement admissible.

N'oubliez pas Public / privé / protégé ne compile que . Une fois que votre application est compilée, des champs privés sont assis à côté des champs publics et il n'y a aucune protection contre la modification. Il en va de même pour les langages gérés tels que C # et Java. < / p>

Vous devez généralement éviter de renvoyer des références car il le rend fou - difficile à comprendre lorsque des constructeurs / destructeurs sont appelés. Cependant, le retour d'une référence peut être plus rapide. Si votre méthode a renvoyé un type d'orme énorme, renvoyant un type d'orme Conston référence à ce même type de structure ne doit prendre que quatre à huit octets (un pointeur sur cet objet). Cependant, il existe de meilleurs moyens d'optimiser pour ce type de chose.


3 commentaires

Je suis fortement fortement en désaccord sur le point "Vous éviter de renvoyer des références de renvoi" - étant donné que le compilateur est libre d'élire les appels au constructeur de copie si vous revenez de valeur, la seule chose que vous gagnez dans de nombreux cas en retournant par la valeur est lente. Builds de débogage (car le compilateur se trouve RVO / NRVO sur vous en mode version).


Ne pas être un utilisateur de gourou de niveau C ++, je me réserve le droit de se tromper :) Mais vous n'obtiendrez-vous pas un comportement indéfini si vous retournez une référence à une variable locale? (C'est-à-dire que vous êtes laissé avec un pointeur à un point aléatoire sur la pile?)


C'est correct. Tenter d'accéder à une variable détruite via des résultats de référence dans un comportement non défini. Mais pour des choses comme des getters de classe de retour en référence, c'est un comportement normal et attendu.



25
votes

privé ne signifie pas "Cette mémoire ne peut être modifiée que par les fonctions de membre" - cela signifie "tentatives directes pour accéder à cette variable entraînera une erreur de compilation". Lorsque vous exposez une référence à l'objet, vous avez effectivement exposé l'objet.

Est-ce une mauvaise pratique de recevoir une variable privée retournée par référence?

Non, cela dépend de ce que vous voulez. Des choses comme std :: vecteur :: opérateur [] serait assez difficile à mettre en œuvre s'ils ne pouvaient pas renvoyer une référence de Const Const :) Si vous voulez Pour renvoyer une référence et ne pas vouloir que les clients puissent la modifier, procédez simplement à une référence const .


2 commentaires

Pour les personnes qui passent: Cette question suggère qu'il peut être dangereux pour renvoyer une référence à vos membres de la classe.


@Arthur: Oui, comme je l'ai dit, cela dépend de ce que vous voulez faire. Ça marche très bien pour std :: vecteur - mais il y a beaucoup de cas où c'est la mauvaise chose à faire aussi.



0
votes

Comme Donotalo a dit, il est parfaitement valide. L'idée d'avoir des membres privés consiste à interdire d'autres classes / fonctions pour accéder au membre privé de la classe sans votre permission. Si vous êtes heureux de faire une fonction pour permettre aux autres classes / fonctions d'accéder à vos membres privés, le compilateur n'a rien contre celui-ci: -)

Habituellement, il est utile d'avoir un membre privé et d'avoir une fonction obtenir pour permettre aux autres classes / fonctions d'obtenir la valeur de la fonction, mais seule la classe sera en mesure de le changer.


0 commentaires

-1
votes

Je suis capable d'accéder à la variable de membre privé en dehors de la portée de la classe

Si vous vous référez au x dans principale () alors qui est différent du x déclaré dans Classe FOO < / code>. Si vous essayez d'accéder au obj.x , le compilateur se plaint certainement.

Est-ce une mauvaise pratique de recevoir une variable privée retournée par référence?

Il n'y a rien de mal dans "recevoir" la référence à un membre privé. Mais donner la référence à un membre privé rend la déclaration inutile privée inutile. En déclarant une variable d'être membre privé, vous limitez l'accès à ce membre uniquement aux méthodes de la classe.

Concernant cette méthode, qu'est-ce que le type de retour transmet? Et aussi quand devrais-je avoir un type de retour de ce type?

Pas sûr de la méthode que vous parlez de la méthode?!?!?!


1 commentaires

Vraiment? Cela le rend inutile? Comment expliquez-vous std :: vecteur :: opérateur [] alors? Quel que soit le pointeur tampon que le vecteur utilise n'est pas exposé au monde, mais les données sont (et doivent être, compte tenu du point du vecteur)