Accessing private class members in C++

Posted on by Idorobots

I've been called Kajtek "MOTHERFU*KINGWALLOFTEXT" Rzepecki lately, so let's make this post short.

We've got this code:

#include <iostream>

class A {
    private:
    int bar;
    void foo() {
        std::cout << "In A::foo() " << bar << "\n";
    }

    public:
    //...
};

int main() {
    A* a = new A();

    //...

    delete a;
    return 0;
}

And we feel a sudden urge to call foo() or access bar. How do we do that? It's quite simple but indicates incredibly poor style1. Seriously, you should feel ashamed just for googling this post, Reader.

Daaamn.

All we really need is a cast:

class B {
    int bar;
    void foo() {}
};

int main() {
    B* a = reinterpret_cast<B*>(new A());

    a->bar = 23;
    a->foo();

    return 0;
}

So far, so good. We can access the fields, but calling foo() yields an unexpected result, well actually expected, it does nothing, just like B::foo() is supposed to do. This is as far as we can go with non-virtual methods.

Let's now pretend that A::foo() was virtual:

class A {
    private:
    int bar;
    virtual void foo() { /* ... */ }
};

class B {
    public:
    int bar;
    virtual void foo() = 0;
};

int main() {
    B* a = reinterpret_cast<B*>(new A());

    a->bar = 23;
    a->foo();

    delete a;
    return 0;
}

This time we create an abstract class with a pure virtual function foo() so we can access whatever foo() there is in A's vtable. This time we get the expected result:

$ ./callfoo
In A::foo() 23

2016-02-20: Adjusted some links & tags.

  1. Again, the private is there for a reason. Casting it away is poor style. Don't do it unless you know what you are doing, which you clearly don't. Daaaamn.