Calling private method in C++

后端 未结 12 2125
忘了有多久
忘了有多久 2020-11-27 20:02

This is purely a theoretical question, I know that if someone declares a method private, you probably shouldn\'t call it. I managed to call private virtual methods and chang

相关标签:
12条回答
  • 2020-11-27 20:47

    Well, the obvious way would be to edit the code so that it is no longer private.

    If you insist on finding an evil way to do it...well...with some compilers it may work create your own version of the header file where that one method is public instead of private. Evil has a nasty way of rebounding on you though (that's why we call it "evil").

    0 讨论(0)
  • 2020-11-27 20:50

    It can be called if a public function returns the address of the private function, then anyone can use that address to invoke the private function.

    Example,

    class A
    {
       void f() { cout << "private function gets called" << endl; }
     public:
         typedef void (A::*pF)();
         pF get() { return &A::f; }
    };
    
    int main() 
    {
            A a;
            void (A::*pF)() = a.get();
            (a.*pF)(); //it invokes the private function!
    }
    

    Output:

    private function gets called
    

    Demo at ideone : http://www.ideone.com/zkAw3

    0 讨论(0)
  • 2020-11-27 20:52

    See my blog post. I'm reposting the code here

    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;
    

    Some class with private members

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

    And how to access them

    struct Af { typedef void(A::*type)(); };
    template class rob<Af, &A::f>;
    
    int main() {
      A a;
      (a.*result<Af>::ptr)();
    }
    
    0 讨论(0)
  • 2020-11-27 20:54

    Define a similar class that is the same apart from the function being public.

    Then typecast an object with the private function to one with the public function, you can then call the public function.

    0 讨论(0)
  • 2020-11-27 20:56

    Followup on T.E.D.'s answer: Don't edit the header. Instead create your own private copy of the header and insert some friend declarations in that bogus copy of the header. In your source, #include this bogus header rather than the real one. Voila!

    Changing private to public might change the weak symbols that result from inlined methods, which in turn might cause the linker to complain. The weak symbols that result from inline methods will have the same signatures with the phony and real headers if all that is done is to add some friend declarations. With those friend declarations you can now do all kinds of evil things with the class such as accessing private data and calling private members.

    Addendum
    This approach won't work if the header in question uses #pragma once instead of a #include guard to ensure the header is idempotent.

    0 讨论(0)
  • 2020-11-27 20:56

    If we are speaking of MSVC, I think the simplest way with no other harm than the fact of calling a private method itself is the great __asm:

    class A
    {
    private:
        void TestA () {};
    };
    
    A a;
    __asm
    {
        // MSVC assumes (this) to be in the ecx.
        // We cannot use mov since (a) is located on the stack
        // (i.e. [ebp + ...] or [esp - ...])
        lea     ecx, [a]
        call    A::TestA
    }
    
    0 讨论(0)
提交回复
热议问题