It depends what kind of ugliness you're prepared to accept. I do almost anything to avoid this kind of fragile hackery, and have never done anything like this in commercial code even for debugging/troubleshooting purposes, but typical suggestions that get thrown around include:
#define private public
before including the header defining the class to be "hacked" (see comments - likely Undefined Behaviour)
- looking for template member functions then specialising them to create a back door - the specialised version can access private members
- in you know the function's implementation you can of course create a similar object in which the function is not private then use casting to invoke it (this has the same kind of propensity for undefined behaviour as the
#define private public
hack above, as they both risk creating an A
-like class with different actual data member layout)
For an example of this last, if you've got access to the .cc/.cpp/.whatever implementation file, you may sometimes be able to do somethign like...
#include "a.h"
#include "a.cc" // normally link a.o to get this - I couldn't be bothered
namespace Hack
{
class A { public: void func(); };
#include "a.cc" // you do have to include this one though...
}
int main()
{
A a;
((Hack::A&)a).func();
}
...I got that working for a simple class A
with func()
implementation file including <iostream>
and invoking std::cout << "x\n";
, but suspect there's potential for show-stopping namespace/symbol clash issues given realistic header and implementation files with complex includes and content.