Acces of the private data of base class without acces modifier

if we don't provide the acces modifiers for base class and we need to manipulate the private data of base class in derived class.
Is there anyway to acces the private data members?
Here's a coding example

class A
{
private :
int a;
};

class B : public class A
{
public :
void displayA() { cout<<a<<endl; }
};

how i can acces the a of base class A in derived class B without acces modifiers.
Last edited on
This is really a design issue. When designing class A, you need to decide whether you want to provide the ability to change the state of a to other classes, including derived classes.

If you want A to provide this ability to all other classes, you need a public interface method that does this.

If you want A to provide this ability only to classes which inherit A, you need a protected interface method.

As things stand, the code in B can't directly access A::a.
The answer (if you really don't want to provide access modifiers) is to change the state of the data member from private to protected

Public: Any part of the program can access this function or member
Protected: Only this class and derived classes can access this function or member
Private: Only this class can access this function or member
Last edited on
@mikeyBoy, @SatsumaBenji, you are right.

i've to extend the functionalities of class A, and i don't have a right to change the code of class A, data members are also private and no acces modifires in A, so is there any legal way to acces the private data memebers of class A in class B.
Last edited on
As already pointed out, without changing the code for class A, you cannot access its private members directly.

Whether you can do so indirectly, depends on how its public/protected member functions are defined.
By default the entire scope of a class is tagged as private until a new modifier is seen by the compiler. You must declare (as protected/public) either the member itself, or a function within the class which edits the member.

Actually... There is a third option which does keep data locked which I've just remembered.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class A{
    int val;
    friend void set(A& arg, int val);
    friend int get(A& arg);
};

void set(A& arg, int val){
    arg.val = val;
}
int get(A& arg){
    return arg.val;
}

int main(){
    A a;
    set(a, 5);
    get(a);
    set(a, 10);
    get(a);
}


A friend function gives an exception to all modifiers in a class, a friend function has permission to access any part of the class it wishes but the class can still use private members;
Last edited on
If you wanted to give the derived class read-only access only you could do this:
1
2
3
4
5
6
7
8
9
10
11
12
13
class A
{
private :
    int a;
protected:
    int getA() { return a; }
};

class B : A
{
public :
    void displayA() { cout<< getA() <<endl; }
};


You can't do what you want without modifying A though.
Last edited on
i still could not get the answer we also don't have to use the friend functions.
Well then I'm afraid that there is no answer, to access a class member there must be a modifier other than private, or a friend declared.
You can also declare friend classes I THINK

1
2
3
4
5
6
7
8
9
10
11
12
class B;

class A{
    int val;
    friend B;
};

class B : private A{
public:
    int get_val(){return A::val};
    void set_val(int v){A::val = v};
}


You could also declare A as a struct instead of a class... Since A holds variables only you can define it as a struct:
1
2
3
4
5
6
struct A{
    int val;
};
class B: public A{
    //whatever you want in B
};
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
class A
{
private :
    int a;
protected:
    int getA() const { return a; }
};

class B : A
{
public :
    void displayA() const { cout<< getA() <<endl; }
};


or you can simply create a const reference which will avoid the function call. Altho I doubt that it'll be noticable. Perhaps the compiler optimizes the function away. Then again, a const reference may be implemented as a pointer (and thus take up more space).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A
{
private :
    A() : ref_a(a) { }
    int a;
protected:
    const int &ref_a;
};

class B : A
{
public :
    void displayA() { cout<< ref_a <<endl; }
};
Hack warning!
Abusing pointers to access private data members.

I have added two getter methods to class A so I can verify that this hack works. I have also generalized the example to include two private members.

I leave it to others to comment on the reliability of these methods which really should not be used.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
using namespace std;

class A
{
    private:
        int x;
        int y;
    public:
        A(int X, int Y): x(X), y(Y) {}

        int get_val(int idx)// get member value
        {
            if(idx==1) return x;
            else return y;
        }

        const int* get_cpval(int idx)// get member address
        {
            if(idx==1) return &x;
            else return &y;
        }
};

int main()
{
    A a(10,20);
    A* pA = &a;

    cout << "pA = " << pA << endl;
    cout << "&a.x = " << a.get_cpval(1) << "\n\n";

    // begin the hack!
    int* pi = (int*)pA;// is pi pointing to a.x?
    cout << "pi = " << pi << "  get_cpval(1) = " << a.get_cpval(1) << "  *pi = " << *pi << endl;
    *pi = 17;// change value of a.x?
    cout << "a.x = " << a.get_val(1) << endl;

    pi += 1;// is pi pointing to a.y?
    cout << "pi = " << pi << "  get_cpval(2) = " << a.get_cpval(2) << "  *pi = " << *pi << endl;
    *pi = 27;// change value of a.y?
    cout << "a.y = " << a.get_val(2) << endl;

    cout << endl;
    return 0;
}

Output:
pA = 0x22ff38
&a.x = 0x22ff38

pi = 0x22ff38  get_cpval(1) = 0x22ff38  *pi = 10
a.x = 17
pi = 0x22ff3c  get_cpval(2) = 0x22ff3c  *pi = 20
a.y = 27


It appears that this hack works!
Last edited on
You're basically doing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

class myprivate {
    myprivate(int x) : a(x) {}
    int a;
};

int main()
{
    myprivate p(42);
    int * pi = (int*)(&p);
    *pi = 32;
    return 0;
}
Yes, that's all it is. The extra code is for verifying that it works.
So is it always that the address of a class object is the same as address of its first member variable?

And what is "first" member variable? Is it the order in which the variables are declared?
abhishekm71 wrote:
is it always that the address of a class object is the same as address of its first member variable

That is true for all standard-layout types (incidentally, these are also the only classes with which offsetof can be used: http://en.cppreference.com/w/cpp/types/offsetof )

ISO wrote:
A standard-layout class is a class that:
— has no non-static data members of type non-standard-layout class (or array of such types) or reference,
— has no virtual functions and no virtual base classes,
— has the same access control for all non-static data members,
— has no non-standard-layout base classes,
— either has no non-static data members in the most derived class and at most one base class with
non-static data members, or has no base classes with non-static data members, and
— has no base classes of the same type as the first non-static data member



And what is "first" member variable? Is it the order in which the variables are declared

yes, but only if all members have the same access control (all public, all private, all protected)

Keep in mind that even though you can reinterpret the address, you can't portably access the member at that address when it breaks strict aliasing
Last edited on
Keep in mind that even though you can reinterpret the address, you can't portably access the member at that address when it breaks strict aliasing


...So what's this mean?
So what's this mean?


http://lmgtfy.com/?q=strict+aliasing

EDIT: And what all these odd, restrictive conditions and rules are really telling you is that, while fun2code's solution is an interesting curiosity, it is a really bad idea to actually do it. As fun2code said in his/her post:

these methods [...] really should not be used

Last edited on
Topic archived. No new replies allowed.