-2

Although it is forbidden in C++, I still want to access a class's non-virtual member function implemented in a library.

Normally, it is impossbile, but is there any hack?

I know some hacks related to accessing virtual private functions, but it seems there is none for non-virtual ones.

Here is an example of the problem:

class A
{
private:
    void func(void);
};

Can func be accessed outside of class A?

jogojapan
  • 68,383
  • 11
  • 101
  • 131
Lane
  • 391
  • 1
  • 2
  • 6
  • 2
    It's not impossible. That's what `friend` is for. – Captain Obvlious May 29 '13 at 05:28
  • 1
    possible duplicate of [Calling private method in C++](http://stackoverflow.com/questions/6873138/calling-private-method-in-c) (This asks specifically for access to non-virtual private methods. I found this by searching Google for "stackoverflow C++ access to private method". Second hit. It's not really that hard. ) – jogojapan May 29 '13 at 05:35
  • @CaptainObvlious: I *think* it's implicit in the question that the class can't be edited to grant additional friendship, but it could be Lane just doesn't know about that option.... – Tony Delroy May 29 '13 at 06:02
  • It looks like the work can be divided into 2 parts, first compile and then link. When compiling, using a new head file, with the same class definition but setting the func with public. Then compiling it as an object file(*.o), and then link it with the original library. It seems working, but I don't know whether there is any side affect – Lane May 30 '13 at 02:38

3 Answers3

2

you can not call private function outside class

Vijay
  • 8,131
  • 11
  • 43
  • 69
  • 2
    Exactly. If there were a way around it, there would be no point in making some methods private. – Kyle G. May 29 '13 at 05:32
2

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.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • 2
    `#define private public` could affect the class layout and cause mismatches between compilation units. It definitely violates the One Definition Rule and gives formally undefined behavior. True, any answers to this question probably will involve UB, but it's still best to explicitly warn about it. – Ben Voigt May 29 '13 at 05:39
  • I think redefining any reserved keyword is formally UB.I actually have seen this in the production code of a relatively large C++ project though... – juanchopanza May 29 '13 at 05:46
  • @BenVoigt: I've added a corresponding comment above, cheers. – Tony Delroy May 29 '13 at 05:56
  • It looks like the work can be divided into 2 parts, first compile and then link. When compiling, using a new head file, with the same class definition but setting the func with public. Then compiling it as an object file(*.o), and then link it with the original library. It seems working, but I don't know whether there is any side affect. – Lane May 30 '13 at 02:33
  • @Lane: the risk is the same as for the `#define` and namespace hackery methods above.... – Tony Delroy May 30 '13 at 02:53
2

You should not access a private member function outside the class even if there is a backdoor using friend class. Use friend as a last resort.

Unless you want to try this for academic purposes, I do not see a reason why you want to do this.

Ram
  • 3,045
  • 3
  • 27
  • 42