Dans les coulisses du public, privé et protégé

Dec 08 2020

J'essaye d'approfondir et de comprendre les différences entre Public | Privé | Protégé dans une perspective de bas niveau, en C ++.

Comment les différences entre les trois sont-elles exprimées dans la mémoire?

Réponses

5 largest_prime_is_463035818 Dec 08 2020 at 20:48

private, publicEt protectedne provoque pas les membres à stocker dans des régions spécifiques de la mémoire. L'accès est vérifié par le compilateur. Au niveau le plus bas, il n'y a pas de différence.

Cependant, les spécificateurs d'accès ont un effet sur les garanties que vous obtenez sur l'ordre dans lequel les membres de la classe sont disposés en mémoire.

À partir du projet de norme C ++ 17 :

Les membres de données non statiques d'une classe (non-union) avec le même contrôle d'accès (Clause [class.access]) sont alloués afin que les membres ultérieurs aient des adresses plus élevées dans un objet de classe. L'ordre d'allocation des membres de données non statiques avec un contrôle d'accès différent n'est pas spécifié (Clause [class.access]). Les exigences d'alignement de la mise en œuvre pourraient empêcher deux membres adjacents d'être attribués immédiatement l'un après l'autre; il en va de même pour les besoins d'espace pour la gestion des fonctions virtuelles ([class.virtual]) et des classes de base virtuelles ([class.mi]).

Cela signifie que pour

 struct foo {
     private:
        int x;
     protected:
        int a;
        int b;
     public:
        int m;
        int n;
     private:
        int y;
};

Vous avez seulement la garantie que la mémoire xvient avant y, avient avant bet mvient avant n. En dehors de cela, l'ordre dans lequel les membres sont disposés en mémoire n'est pas spécifié.

Cependant, l'ordre des membres en mémoire est rarement une information utile. Il n'est donc pas trop faux de dire que les spécificateurs d'accès n'ont rien à voir avec la "mémoire de bas niveau".

2 SergeBallesta Dec 08 2020 at 20:44

Au niveau le plus bas (représentation en octets des objets), il n'y a absolument aucune différence entre public, privé et protégé. La plupart des compilateurs peuvent (mais ne sont pas obligés de) réorganiser les membres en fonction de leur visibilité.

Au niveau intermédiaire (comportement d'exécution), il y a peu ou pas de différence. Si vous pouvez trouver un pointeur public vers une donnée privée, vous pouvez l'utiliser en toute sécurité. Plus précisément, cela est différent de constness où l'utilisation d'un pointeur non const pour modifier les données const est explicitement un comportement indéfini et peut provoquer des erreurs SIGSEGV.

La différence n'est qu'au niveau le plus élevé. Vous pouvez utiliser des membres publics de n'importe où, tandis que les membres privés ne peuvent être utilisés que dans la classe où ils sont déclarés et les membres protégés peuvent être utilisés à partir de leur classe et de toutes les classes qui en héritent - mais la convivialité peut permettre à des classes de fonctions spécifiques d'accéder à private ou protected Les données.

Yunnosch Dec 08 2020 at 20:35

Pas du tout.

L'accès est "accordé / refusé" par le compilateur.

Tout accès ne correspondant pas à une visibilité appropriée (telle que contrôlée par la classe de l'objet accédé, via un pointeur ou non) est empêché avant la construction.

Remarque:

Les autres réponses discutent utilement de l'effet de la visibilité sur l'ordre en mémoire.

J'ai cependant répondu à la question différente que j'ai lue dans le post des OP "Comment les fonctionnalités de protection de la mémoire sont-elles utilisées pour implémenter l'accessibilité / la visibilité des membres?", Qui concernant la cause et l'effet est une sorte de question inverse. Ou seulement la commande / structuration des éléments dans des mémoires configurées différemment est l'outil pour obtenir l'effet de visibilité souhaité, qui à son tour exigerait (mais ne provoquerait pas) l'ordre des éléments d'une certaine manière.

C'est-à-dire que je ne vois pas de conflit entre les réponses, juste une interprétation différente de la question.