Accessing private class members in C++

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 style*. 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

* 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.

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s