web-dev-qa-db-fra.com

Comment accéder aux données privées des membres en dehors de la classe sans se faire des "amis"?

J'ai un class A comme mentionné ci-dessous:-

class A{
     int iData;
};

Je ne veux ni créer de fonction membre ni hériter de ce qui précède class A ni modifier le spécificateur de iData.

Mes doutes: -

  • Comment accéder à iData d'un objet, dites obj1 qui est une instance de class A?
  • Comment modifier ou manipuler le iData d'un objet obj1?

Remarque: N'utilisez pas friend.

15
Abhineet

Tu ne peux pas. Ce membre est privé, il n'est pas visible en dehors de la classe. C'est tout l'intérêt des modificateurs public/protégé/privé.

(Vous pouvez probablement utiliser des astuces de pointeur sales, mais je suppose que vous entrez assez rapidement dans un territoire de comportement indéfini.)

8
Mat

Voici un moyen, non recommandé cependant

class Weak {
private:
    string name;

public:
    void setName(const string& name) {
        this->name = name;
    }

    string getName()const {
        return this->name;
    }

};

struct Hacker {
    string name;
};

int main(int argc, char** argv) {

    Weak w;
    w.setName("Jon");
    cout << w.getName() << endl;
    Hacker *hackit = reinterpret_cast<Hacker *>(&w);
    hackit->name = "Jack";
    cout << w.getName() << endl;

}
20
Sleiman Jneidi

MODIFIER:
Je viens de voir que vous avez modifié la question pour dire que vous ne voulez pas utiliser d'ami.
Alors la réponse est:

NON vous ne pouvez pas, du moins pas de manière portable approuvée par la norme C++.


La dernière partie de la réponse était antérieure à l'édition Q et je la laisse ici au profit de> ceux qui voudraient comprendre quelques concepts et pas seulement chercher une réponse à la> question .


Si vous avez des membres sous un spécificateur d'accès privé, ces membres ne sont accessibles que depuis la classe. Aucun accès extérieur n'est autorisé.

n exemple de code source:

class MyClass
{
    private:
        int c;
    public:
    void doSomething()
    {
        c = 10;    //Allowed 
    }
};

int main()
{
    MyClass obj;
    obj.c = 30;     //Not Allowed, gives compiler error
    obj.doSomething();  //Allowed
}

ne solution de contournement: friend à sauver
Pour accéder au membre privé, vous pouvez déclarer une fonction/classe comme ami de cette classe particulière, puis le membre sera accessible à l'intérieur de cette fonction ou objet de classe sans vérification du spécificateur d'accès.

Exemple de code modifié:

class MyClass
{
    private:
        int c;

    public:
    void doSomething()
    {
        c = 10;    //Allowed 
    }

    friend void MytrustedFriend();    
};

void MytrustedFriend()
{
        MyClass obj;
        obj.c = 10; //Allowed
}

int main()
{
    MyClass obj;
    obj.c = 30;     //Not Allowed, gives compiler error
    obj.doSomething();  //Allowed
    //Call the friend function
    MytrustedFriend();
    return 0;
}
10
Alok Save

Mauvaise idée, ne le faites jamais - mais voici comment cela peut être fait:

int main()
{
   A aObj;
   int* ptr;

   ptr = (int*)&aObj;

   // MODIFY!
   *ptr = 100;
}
9
Ajay

http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html

le blog de ce type vous montre comment le faire à l'aide de modèles. Avec quelques modifications, vous pouvez adapter cette méthode pour accéder à un membre de données privées, bien que je l'ai trouvé difficile malgré 10 ans d'expérience.

Je voulais souligner, comme tout le monde, qu'il existe un nombre extrêmement limité de cas où cela est légitime. Cependant, je veux en souligner un: j'écrivais des tests unitaires pour une suite logicielle. Un organisme de réglementation fédéral exige que chaque ligne de code soit exercée et testée, sans modification du code d'origine. En raison de la mauvaise conception (à mon humble avis), une constante statique était dans la section "privée", mais je devais l'utiliser dans le test unitaire. La méthode m'a donc semblé être la meilleure façon de le faire.

Je suis sûr que la voie pourrait être simplifiée, et je suis sûr qu'il existe d'autres façons. Je ne poste pas cela pour l'OP, car cela fait 5 mois, mais j'espère que cela sera utile à un futur googleur.

7
Timmah

Il n'y a aucun moyen légitime de le faire.

3
RocketR

En C++, presque tout est possible! Si vous n'avez aucun moyen d'obtenir des données privées, vous devez pirater. Faites-le uniquement pour les tests!

class A {
     int iData;
};

int main ()
{
    A a;
    struct ATwin { int pubData; }; // define a twin class with public members
    reinterpret_cast<ATwin*>( &a )->pubData = 42; // set or get value

    return 0;
}
3
Alexander Drichel

iData est un membre private de la classe. Maintenant, le mot private a une signification très définie, en C++ comme dans la vie réelle. Cela signifie vous ne pouvez pas le toucher. Ce n'est pas une recommandation, c'est la loi. Si vous ne modifiez pas la déclaration de classe, vous n'êtes pas autorisé à manipuler ce membre de quelque manière que ce soit, forme ou forme.

2
n.m.

Il est possible d'accéder aux données privées de la classe directement dans la fonction principale et autre ...

voici un petit code ...

class GIFT
{
    int i,j,k;

public:
    void Fun() 
    {
        cout<< i<<" "<< j<<" "<< k;
    }

};

int main()
{
     GIFT *obj=new GIFT(); // the value of i,j,k is 0
     int *ptr=(int *)obj;
     *ptr=10;
     cout<<*ptr;      // you also print value of I
     ptr++;
     *ptr=15;
     cout<<*ptr;      // you also print value of J
     ptr++;
     *ptr=20; 
     cout<<*ptr;      // you also print value of K
     obj->Fun();
}
2
GIFT.azib

ami est votre ami.

class A{
    friend void foo(A arg);
    int iData;
};

void foo(A arg){
     // can access a.iData here
}

Si vous faites cela régulièrement, vous devriez probablement reconsidérer votre conception.

2
James

Commencez à créer friends de class A. par exemple.

void foo ();

class A{
  int iData;
  friend void foo ();
};

Modifier :

Si vous ne pouvez pas changer class A corps puis A::iData n'est pas accessible avec les conditions données dans votre question.

2
iammilind