Pourquoi ne puis-je exposer les membres privés quand je retourner une référence à partir d'une fonction membre public?
Dans l'extrait de code, je suis en mesure d'accéder à la variable membre privée en dehors de la portée de classe. Bien que cela ne devrait jamais être fait, pourquoi est-il permis dans ce cas? Est-ce une mauvaise pratique de recevoir en retour une variable privée par référence ?
#include <iostream>
#include <cstdlib>
class foo
{
int x;
public:
foo(int a):x(a){}
int methodOne() { return x; }
int& methodTwo() { return x; }
};
int main()
{
foo obj(10);
int& x = obj.methodTwo();
x = 20; //With this statement, modifying the state of obj::x
std::cout << obj.methodOne();
getchar();
return 0;
}
Et au sujet de cette méthode, quel est le type de retour de transmettre ? Et aussi quand je dois le type de retour de ce genre ?
int& methodTwo() { return x; }
PS: je suis désolé si la ligne de sujet est vague. Quelqu'un peut-il modifier le contenu pertinent ici. Merci.
OriginalL'auteur Mahesh | 2011-01-16
Vous devez vous connecter pour publier un commentaire.
private
ne veut pas dire "cette mémoire ne peut être modifié que par les fonctions membres", qui signifie "direct les tentatives d'accès à cette variable va entraîner une erreur de compilation". Lorsque vous exposez une référence à l'objet, que vous avez exposé l'objet.Non, cela dépend de ce que vous voulez. Des choses comme
std::vector<t>::operator[]
serait assez difficile à mettre en œuvre si ce n'était pas un non-const
référence 🙂 Si vous voulez retourner une référence et ne veulent pas les clients à être en mesure de le modifier, il suffit de faire unconst
de référence.Oui, comme je l'ai dit, ça dépend de ce que vous voulez faire. Il fonctionne très bien pour
std::vector
-- mais il y a beaucoup de cas où c'est la mauvaise chose à faire trop.OriginalL'auteur Billy ONeal
Retour privée membres de référence est parfaitement valide et le programmeur qui écrit une classe est responsable de choisir soigneusement si ce devrait être autorisé. Ce lien donne un exemple quand cela peut être fait.
OriginalL'auteur Donotalo
Ce code:
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é, la valeur quemethodTwo
retourné. Dans ce cas, le champ classe dex
.Dans le code que vous avez écrit, cela signifie que vous laissez à la variable privée
x
échapper à son champ (un champ de classe) et être passé autour du monde extérieur. C'est certainement une mauvaise pratique (parce quex
peut être modifié d'une manière qui peut briser la classefoo
, mais il est certainement admissible.Rappelez-vous public/privé/protégé de la compilation seulement. Une fois que votre application est compilée, champs privés s'asseoir à côté de champs publics et il n'y a pas de protection contre les modifications. Le même est vrai pour les langages comme C# et Java.
Il est généralement préférable d'éviter de se retrouver les références, car il rend fou-difficile à comprendre quand les constructeurs/destructeurs appelée. Toutefois, en retournant une référence peut être plus rapide. Si votre méthode a renvoyé un type struct qui est ÉNORME, retour const référence à ce même type struct ne devrait prendre de quatre à huit octets (un pointeur vers cet objet). Cependant, il existe de meilleures façons d'optimiser votre site pour ce genre de chose.
Ne pas être un gourou de niveau C++ utilisateur, je me réserve le droit de se tromper 🙂 Mais ne sera pas vous obtenir un comportement indéfini si vous renvoyer une référence à une variable locale? (I. e., vous êtes de gauche avec un pointeur à certains endroit aléatoire sur la pile?)
Qui est correct. Tentative d'accès à une détruits variable par référence provoque un comportement indéfini. Mais pour des choses comme la classe des getters retour par référence est normal et le comportement attendu.
OriginalL'auteur Chris Smith
Comme Donotalo dit, il est parfaitement valide. L'idée d'avoir privé, est d'empêcher les autres classes/fonctions d'accès à la membre privé de la classe sans votre permission. Si vous êtes heureux de faire une fonction pour permettre à d'autres classes/fonctions pour accéder à vos membres, le compilateur n'a rien contre que vraiment 🙂
Généralement, il est utile d'avoir un membre privé et un obtenir fonction de permettre à d'autres classes/fonctions pour obtenir la valeur de la fonction, mais seulement la classe sera en mesure de le changer.
OriginalL'auteur Rafid
Si vous faites référence à la
x
dansmain()
alors que c'est différent de lax
déclaré dansclass foo
. Si vous essayez d'accéder à laobj.x
puis le compilateur va certainement se plaindre.Il n'y a rien de mal à "recevoir" la référence à un membre privé. Mais en donnant la référence à un membre privé fait de déclarer privé inutile. Par la déclaration d'une variable à un membre privé de restreindre l'accès aux seuls membres de la classe des méthodes.
Pas sûr que la méthode dont vous parlez?!?!?!
std::vector<t>::operator[]
alors? Quelle que soit pointeur de la mémoire tampon le vecteur est l'aide n'est pas exposé au monde, mais les données sont (ou devraient l'être, compte tenu de la point du vecteur)O'Neal: Bon point. Merci pour le tuyau.
OriginalL'auteur yasouser