7
votes

Puis-je transformer un objet et accéder aux membres de données privés en C ++?

Je veux accéder à un membre de données privé dans une classe. Il n'y a pas de fonction de membre dans la classe pour accéder au membre de données privé. C'est privé.

Je veux prendre la classe et certains à quel point il est ouvert. Une méthode consistait à copier la déclaration de la classe, à rendre le membre privé public et à appeler la nouvelle classe de classe quelque chose_else. Ensuite, je fais une réinterprétation et copiez l'objet d'origine. Cela marche. Mais je veux quelque chose de plus élégant ... ou peut-être générique ... ou juste d'une autre manière.

Quelles options y a-t-il? Puis-je utiliser Void *? Puis-je mémoriser la classe dans une autre classe vide? Que sont les moyens de faire cela ??

%


5 commentaires

Que diriez-vous d'éditer la source? // privé: fonctionnera très bien;)


Je pense qu'il veut conserver les utilisateurs de sa classe de jouer autour (donc le privé) et doit mettre en œuvre quelque chose qui ne correspond pas vraiment à la conception actuelle.


Je pense que vous n'avez pas le code, n'est-ce pas?


@Liranuna: Commenter le «Private: 'Tag fonctionnera dans certaines situations, mais peut subtilement casser du code dans d'autres. Vous pouvez modifier subtilement un type non de pod en une pod et la langue a des règles légèrement différentes pour ces types.


Je pense que nous devrons savoir pourquoi vous voulez cela. La réponse dépend beaucoup de ce que vous essayez d'atteindre.


6 Réponses :


19
votes

Je suppose que

  1. Vous avez déjà été via "L'encapsulation de rupture est mauvaise" étape,
  2. Épuisé Autres solutions possibles,
  3. ne peut pas changer d'en-tête de classe.

    Il y a quelques façons de subverser l'accès aux membres privés d'une classe, comme démontré dans gotw # 76 .

    1. Dupliquer une définition de classe et ajoutez un ami DÉCLARATION.
    2. Utilisez Evil Macros: #define Private Public Avant d'inclure la classe 'Header . .
    3. Écrivez une définition de classe avec une mise en page binaire identique et utilisez Reterpret_cast pour passer de la classe d'origine à un faux.
    4. Spécialisez une fonction de membre de modèle s'il y en a une (la seule solution portable).

1 commentaires

Aimer les macros diaboliques mentionnent;)



1
votes

Vous pouvez, mais vous ne devriez pas. Les objets ne sont que de la mémoire. Vous pouvez certainement lancer le pointeur en une classe équivalente qui a les mêmes membres, mais où tout est public. Mais pourquoi voulez-vous faire cela? Avez-vous le code de quelqu'un d'autre que vous devez travailler? Demandez-leur d'ajouter des méthodes appropriées d'accesseur. Avez-vous vraiment besoin de les traiter comme membres du public? Changer la classe.

Je ne suis pas vraiment sûr de ce que vous essayez de faire, mais c'est probablement une erreur.


0 commentaires

0
votes

Je suis d'accord avec le commentaire "Modifier la source", mais je pense que vous devriez ajouter une méthode, pas seulement commentez le "privé".

Vous devez avoir la déclaration de la classe, vous avez donc probablement l'en-tête mais éventuellement pas le fichier .CPP / quel que soit le fichier. Ajoutez une fonction de membre en ligne à la classe dans une copie de l'en-tête et incluez cet en-tête au lieu de l'original. Vous devriez toujours pouvoir créer un lien vers le fichier d'objet pour le code source inaccessible.

Bien sûr, cela compte comme un piratage diabolique, contournant les protections intégrées dans la langue plutôt que de travailler avec eux. C'est pourquoi je suggère le hack minimalement diabolique - ne faites pas tout de pair privé, et si vous pouvez vous échapper avec un getter (mais aucun seint) le faire. Bien sûr, le vrai mal minimal n'est pas de le faire, s'il y a du tout pour l'éviter.

N'oubliez pas que si c'est une classe d'Elesse, la prochaine version pourrait être mise en œuvre différemment et pourrait ne pas avoir ce membre du tout.


0 commentaires

3
votes

Avec l'idée que vous suggérez dans votre question, vous n'avez pas besoin de copier l'objet d'origine. Si vous écrivez votre propre variation «TOUT PUBLI» de la Déclaration de la classe réelle, lancez un pointeur sur ce nouveau type, vous pouvez accéder directement à l'objet à travers celui-ci.

La raison pour laquelle rien de tout cela n'est une bonne idée n'est simple. Vous devez manipuler des objets d'une classe dont vous ne contrôlez pas la source (sinon vous pourrez modifier la source pour vous donner l'accès dont vous avez besoin). Mais si vous ne contrôlez pas la source, alors si les responsables changent la mise en page de leur classe? Votre version dupliquée ne correspondra plus et il n'y aura aucun moyen pour le compilateur de détecter cette inadéquation. Le résultat sera probablement la corruption de la mémoire au moment de l'exécution.


0 commentaires

3
votes

Comme il est mal compris, je dois clarifier. Toutes les solutions suivantes ne vous obligent pas à recompiler l'objet fort>. Pour utiliser une classe dans votre code, si elle est compilée dans un fichier d'objet, vous devez inclure un fichier d'en-tête avec la déclaration de cette classe.

#include <class_fixed.h>
ObjectFoo instance;


0 commentaires

0
votes

merci ... je voulais montrer le code de mon correctif d'origine. La raison en tant que quelqu'un a atteint, c'est que je ne peux pas changer le code d'origine ... Je dois donc faire une pause de prison.


xxx

Ceci fonctionne ... mais je pense que je veux quelque chose de plus générique ... ou plus flexible.

%


2 commentaires

De nombreuses réponses ici ont supposé que vous ne pouvez pas modifier le code d'origine .cpp , pendant que vous pouvez modifier - ou simplement copier, renommer et réinclude - le fichier en-tête . Re-lisez les réponses avec cette idée.


Il est beaucoup préférable d'ajouter ces informations à la question initiale plutôt que de l'ajouter comme une réponse.