-3

Clarification: This question originally came from a challenge I thought of, and isn't connect with programming for real systems.

Suppose I have a class, that I know its' architecture which I can't change, and I don't want to inherit it, but I do want to get access to its' private data and functions. How can I do it?

Suppose my class looks like this one:

class A {
public:
    int v = 89;

private:
    int a = 5;
    virtual void function(int a, int b) {
        cout << a << " " << b << endl;
    }
};
Coral Kashri
  • 3,436
  • 2
  • 10
  • 22
  • 2
    The only proper answer would be to *not* do it, and instead make a sound and proper design that doesn't require hard to read, understand and maintain hacks. Especilly since hacks like that will break a number or rules (like perhaps the [the strict aliasing rule](https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule), and more) and will most likely lead to [*undefined behavior*](https://en.wikipedia.org/wiki/Undefined_behavior). It is also very implementation specific, and even changing compiler version or hardware platform may cause the hack to not work anymore. – Some programmer dude Jul 27 '18 at 17:55
  • 2
    @Someprogrammerdude even more likely: changing optimization levels or inlining occasions. This can work fine, then a function call gets in the way and it catches fire. – Quentin Jul 27 '18 at 17:56
  • 1
    `#define private public` before including this file – alter_igel Jul 27 '18 at 17:57
  • @alterigel [nope, still UB](https://stackoverflow.com/a/45901227/3233393). – Quentin Jul 27 '18 at 17:58
  • Why ask a question and then answer it yourself? Also... your function "function" has a parameter 'a' which hides the private variable of the same name. – Tim Randall Jul 27 '18 at 18:00
  • 3
    @TimRandall [Self answering is perfectly acceptable](https://stackoverflow.com/help/self-answer). – Passer By Jul 27 '18 at 18:01
  • 2
    @TimRandall that's actually encouraged! SO is all about benefiting future researchers who encounter similar problems. – Quentin Jul 27 '18 at 18:02
  • Thanks for the info. Apologies for posting my comment before it was finished (I wasn't expecting the Enter key to do that.) – Tim Randall Jul 27 '18 at 18:04
  • @TimRandall "Also... your function "function" has a parameter 'a' which hides the private variable of the same name" - I know, my target was the idea how to access the function, so it doesn't matter for my issue. – Coral Kashri Jul 27 '18 at 18:08
  • I think that what you are trying to propose breaks the idea of data encapsulation. AFAIK there is no safe proper way of doing this without either A: modifying the original in which you stated you can not, or by using some form of interpretation that can and probably will lead to UB which is never good. – Francis Cugler Jul 27 '18 at 18:21

2 Answers2

1

a while ago stumbled upon a neat template trick to do this on this blog: http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html

Do NOT use this in any production code, it is just a educational example !!!

it takes basically leverage of the "private" being ignored on some part of template initialization

template<typename Tag>
struct result {
    /* export it ... */
    typedef typename Tag::type type;
    static type ptr;
};

template<typename Tag>
typename result<Tag>::type result<Tag>::ptr;

template<typename Tag, typename Tag::type p>
struct rob : result<Tag> {
    /* fill it ... */
    struct filler {
        filler() { result<Tag>::ptr = p; }
    };
    static filler filler_obj;
};

template<typename Tag, typename Tag::type p>
typename rob<Tag, p>::filler rob<Tag, p>::filler_obj;

usage: take following struct:

struct A {
private:
    void f() {
        std::cout << "proof!" << std::endl;
    }
};

create your "robber"

struct Af { typedef void(A::*type)(); };
template class rob<Af, &A::f>;

use it:

int main()
{
    A a;
    (a.*result<Af>::ptr)();

    return 0;
}
skeller
  • 1,151
  • 6
  • 6
-1

A less risky hack will be to make your function/class a friend of the class if you are allowed to modify just the header file.

// Add
class HackA;

class A {
public:

    // Add
    friend class HackA;

    int v = 89;

private:
    int a = 5;
    virtual void function(int a, int b) {
        cout << a << " " << b << endl;
    }
};

Now you can use:

class HackA {
public:
    int number(A const& a) { return a.v; }
    int another_number(A const& a) { return a.a; }
    void target_function(A& a, int number, int another_one)
    {
       a.function(number, another_one);
    }
};

int main()
{
    A a;
    HackA hacker

    cout << hacker.number(a) << " " << hacker.another_number(a) << endl;
    hacker.target_function(a, 9, 3);

    return 0;
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 1
    As I mentioned, this question is referring to a case that you can't edit the target class. If you can edit this class, just add getters and setters.. – Coral Kashri Jul 27 '18 at 18:04
  • @KorelK, I didn't notice anything in your post about not being able to modify the .h file. – R Sahu Jul 27 '18 at 18:09
  • 2
    "Suppose I have a class, that I know its' architecture which I can't change" – Coral Kashri Jul 27 '18 at 18:10
  • @KorelK, I see. I read that very differently -- I read that to mean you can't add/remove/modify member variables or member functions. – R Sahu Jul 27 '18 at 18:12
  • 1
    If you are allowed to modify header file what stops anyone from adding the public definition for a getter `int getA() { return a; }` into header? – Killzone Kid Jul 27 '18 at 18:22
  • @KillzoneKid, it is less risky because you are not modifying the interface/implementation of the class. – R Sahu Jul 27 '18 at 18:23