I want to access private members without modifying the .h file. This is an example of a .h file
class X
{
private:
class A
{...};
vector<A> arr;
}
Q:How can I access X::arr ?
class X
{
private:
int a;
};
template<typename Tag, typename Tag::type Member>
struct XAccessor
{
friend typename Tag::type get(Tag)
{
return Member;
}
};
struct X_A
{
typedef int X::* type;
friend type get(X_A);
};;
template struct XAccessor<X_A, &X::a>;
...
auto x = new X;
x->*get(X_A())=11;
...
I found this approach online, but when I changed typedef int X::* type to typedef vector<X::A> X::* type, it gave me an error saying that X::A is not accessible.
If you can steal the data member pointer, you can extract the type from it. Here is a solution that works with zero modifications to the original
X.Say we have a class
Xwhich we can't modify, containing a private data member of private typeHidden. In your example,Hidden = std::vector<A>.We can create a function that returns the data member pointer
X::*a, without naming the typeX::Hidden:The reason why this works is that member access restrictions are disabled when explicitly instantiating templates, so
Thief<&X::a>will not fail to compile. This is intentional design, because otherwise you would be unable to explicitly instantiate any templates involving non-public members.Thiefdefines a hidden friendsteal(), which returns the data member pointer, and acts as a "jailbreak" for encapsulation.steal()is just a free function, and doesn't contain&X::aorX::Hiddenin any template parameters or function parameters, so nothing restricts our access to it.We also create a type trait so we can extract the data type from this pointer:
Finally, we are able to access both the private type
X::Hidden, and the private data memberX::a:See live demo on Compiler Explorer.