22

I have a class A as mentioned below:-

class A{
     int iData;
};

I neither want to create member function nor inherit the above class A nor change the specifier of iData.

My doubts:-

  • How to access iData of an object say obj1 which is an instance of class A?
  • How to change or manipulate the iData of an object obj1?

Note: Don't use friend.

iammilind
  • 68,093
  • 33
  • 169
  • 336
Abhineet
  • 6,459
  • 10
  • 35
  • 53
  • Can you change the declaration of that class at all? – Mat Jul 16 '11 at 11:57
  • No i dont want to change the declaration of that class. – Abhineet Jul 16 '11 at 12:00
  • It seems that in SO, you are verifying whether `private` access specifier works fine or not. – iammilind Jul 16 '11 at 12:20
  • 1
    @greengit: The question was for my awareness that whether we can do by some or other way or not. – Abhineet Jul 16 '11 at 12:23
  • Sounds like 'How do I make it work if I don't want to change anything?'. Is it a legacy or third-party code which you can't change but you need to access that member? – RocketR Jul 16 '11 at 12:26
  • @RocketR: Anyone has answer for `RocketR` question? :) – Abhineet Jul 16 '11 at 12:35
  • @Abhineet: Next time you post a Q, you post all your requirements/expectations at the time of asking and not change them once people start answering & down voting them for not noticing your edits. It is your responsibility as a Q poster to post a clear, concise Q. – Alok Save Jul 16 '11 at 12:44
  • @Als: Yes friend i am sorry for that. And thanks for your support. – Abhineet Jul 16 '11 at 12:46

12 Answers12

39

Here's a way, not recommended though

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;

}
Community
  • 1
  • 1
Sleiman Jneidi
  • 22,907
  • 14
  • 56
  • 77
  • 2
    Note -- If the class has a vtable (`std::is_polymorphic()`) you need to declare an additional `void *` as the first member. Needless to say this is a dirty hack on top of another dirty hack - avoid doing it. – dialer Mar 07 '20 at 18:09
15

Bad idea, don't do it ever - but here it is how it can be done:

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

   ptr = (int*)&aObj;

   // MODIFY!
   *ptr = 100;
}
Ajay
  • 18,086
  • 12
  • 59
  • 105
12

You can't. That member is private, it's not visible outside the class. That's the whole point of the public/protected/private modifiers.

(You could probably use dirty pointer tricks though, but my guess is that you'd enter undefined behavior territory pretty fast.)

Mat
  • 202,337
  • 40
  • 393
  • 406
  • 3
    [friend](http://en.wikipedia.org/wiki/Friend_function) [friend](http://en.wikipedia.org/wiki/Friend_class) ... my friend :) – treecoder Jul 16 '11 at 12:14
  • 4
    The question reads: `Please note: I dont want to use friend`. – Mat Jul 16 '11 at 12:17
  • @greengit: there is a worth in it, i have clarified my doubt. Atleasst for me it means a lot my friend. :) – Abhineet Jul 16 '11 at 12:49
  • "You can't" - so you're saying this is incorrect and/or UB? http://bloglitb.blogspot.com/2011/12/access-to-private-members-safer.html – xaxxon Sep 03 '18 at 22:10
  • @xaxxon: that code uses a `friend`-based trick. – Mat Sep 04 '18 at 04:56
  • @Mat if it's not UB, then perhaps you would consider changing your answer - especially because it's the accepted answer and people may take it to be accurate without reading all the comments. – xaxxon Sep 04 '18 at 17:54
  • @xaxxon: This question is about private access **without** using `friend`. Your article uses `friend`. – Mat Sep 05 '18 at 04:59
  • @Mat I guess you're technically right, but I would assume they meant not adding `friend` to the class where you want to get access. There's no reason to artificially limit what can be done outside the class. – xaxxon Sep 05 '18 at 16:14
11

EDIT:
Just saw you edited the question to say that you don't want to use friend.
Then the answer is:

NO you can't, atleast not in a portable way approved by the C++ standard.


The later part of the Answer, was previous to the Q edit & I leave it here for benefit of >those who would want to understand a few concepts & not just looking an Answer to the >Question.


If you have members under a Private access specifier then those members are only accessible from within the class. No outside Access is allowed.

An Source Code Example:

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
}

A Workaround: friend to rescue
To access the private member, you can declare a function/class as friend of that particular class, and then the member will be accessible inside that function or class object without access specifier check.

Modified Code Sample:

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;
}
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • But we can use making friend of class A. – Abhineet Jul 16 '11 at 12:01
  • `I dont want to create member function for above class A`. Also your `A::doSomething()` is private. This code results in compile error. – iammilind Jul 16 '11 at 12:04
  • @iammilind: Can you not see `public` not being there a typo & well the answer in all completeness answers what options C++ provides. It also includes what fits his/her specification. I suggest you try having a broader view of things. – Alok Save Jul 16 '11 at 12:08
  • @Downvoters: Any explanations for your downvotes? – Alok Save Jul 16 '11 at 12:17
  • Would the second code example work if inside the friend function, you dereferenced the class to access the private member using the `->` operator? e.g. `MyClass* obj = /* ... */; obj->private_member = /* ... */;` – Zenul_Abidin Feb 01 '22 at 16:36
8

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

this guy's blog shows you how to do it using templates. With some modifications, you can adapt this method to access a private data member, although I found it tricky despite having 10+ years experience.

I wanted to point out like everyone else, that there is an extremely few number of cases where doing this is legitimate. However, I want to point out one: I was writing unit tests for a software suite. A federal regulatory agency requires every single line of code to be exercised and tested, without modifying the original code. Due to (IMHO) poor design, a static constant was in the 'private' section, but I needed to use it in the unit test. So the method seemed to me like the best way to do it.

I'm sure the way could be simplified, and I'm sure there are other ways. I'm not posting this for the OP, since it's been 5 months, but hopefully this will be useful to some future googler.

Timmah
  • 177
  • 1
  • 2
  • `every single line of code to be exercised and tested` oh my. that's bitterly stupid. http://rbcs-us.com/documents/Why-Most-Unit-Testing-is-Waste.pdf – v.oddou Jun 30 '16 at 08:44
  • @v.oddou Interesting article, but that's just an opinion. There are [others](https://stackoverflow.com/a/479622/). And of course these opinions are heavily disputed. We don't need to repeat that here. Just a question: when you refactor, how do you know you don't break things? I agree with Jim Coplien that "unit test" is not the answer to everything. But "not testing" is not a solution either. – Adrian W Jun 18 '18 at 20:27
  • Of course I don't agree with everything in this article. eg the "1 trillionth" coverage, is rhetoric crap (because of recurrence relation that he conveniently swept under the carpet). What you say is also valid. Also he is stupidely idealistic: `Tests should be designed with great care. Business people, rather than programmers` LLOL – v.oddou Jun 19 '18 at 02:37
4

In C++, almost everything is possible! If you have no way to get private data, then you have to hack. Do it only for testing!

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;
}
EmpathicSage
  • 1,265
  • 8
  • 11
3

There's no legitimate way you can do it.

RocketR
  • 3,626
  • 2
  • 25
  • 38
  • I have clearly mentioned above that i dont want to change the behaviour. – Abhineet Jul 16 '11 at 12:39
  • 1
    @RocketR: +1, to compensate downvotes for a Q that was edited and modified later on. – Alok Save Jul 16 '11 at 12:54
  • @Als: Earlier he has mentioned to do the following struct A{ int iData }; I have never told that i want to replace the keyword `class` with `struct`. And edition was to not to use friend not the other things... – Abhineet Jul 16 '11 at 13:01
  • 1
    @Abhineet: Given the wide context of the Q that was put forward when it was posted, I would not discount that as an outright wrong answer. – Alok Save Jul 16 '11 at 13:03
2

It's possible to access the private data of class directly in main and other's function...

here is a small 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();
}
Jesse
  • 8,605
  • 7
  • 47
  • 57
GIFT.azib
  • 21
  • 1
2

Start making friends of class A. e.g.

void foo ();

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

Edit:

If you can't change class A body then A::iData is not accessible with the given conditions in your question.

iammilind
  • 68,093
  • 33
  • 169
  • 336
2

iData is a private member of the class. Now, the word private have a very definite meaning, in C++ as well as in real life. It means you can't touch it. It's not a recommendation, it's the law. If you don't change the class declaration, you are not allowed to manipulate that member in any way, shape or form.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
1

friend is your friend.

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

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

If you're doing this regularly you should probably reconsider your design though.

James
  • 24,676
  • 13
  • 84
  • 130
-1

access private members outside class ....only for study purpose .... This program accepts all the below conditions "I dont want to create member function for above class A. And also i dont want to inherit the above class A. I dont want to change the specifier of iData."

//here member function is used only to input and output the private values ... //void hack() is defined outside the class...

//GEEK MODE....;)
#include<iostream.h>
#include<conio.h>

    class A
    {
    private :int iData,x;
    public: void get()             //enter the values
        {cout<<"Enter iData : ";
            cin>>iData;cout<<"Enter x : ";cin>>x;}

        void put()                               //displaying values
    {cout<<endl<<"sum = "<<iData+x;}
};

void hack();        //hacking function

void main()
{A obj;clrscr();
obj.get();obj.put();hack();obj.put();getch();
}

void hack()         //hack begins
{int hck,*ptr=&hck;
cout<<endl<<"Enter value of private data (iData or x) : ";
cin>>hck;     //enter the value assigned for iData or x
for(int i=0;i<5;i++)
{ptr++;
if(*ptr==hck)
{cout<<"Private data hacked...!!!\nChange the value : ";
cin>>*ptr;cout<<hck<<" Is chaged to : "<<*ptr;
return;}
}cout<<"Sorry value not found.....";
}