Able to use pointer to function to call private method of an external class

瘦欲@ 提交于 2019-12-12 10:29:42

问题


Based on the following answer to a recent question, I'm able to use a function pointer in order to call the private method Foo<T>::foo() from another class Bar, as shown below (see also ideone)

#include <iostream>

template<typename T>
struct Bar
{
    typedef void (T::*F)();

    Bar( T& t_ , F f ) : t( t_ ) , func( f )
    {
    }

    void operator()()
    {
        (t.*func)();
    }

    F func;
    T& t;
};

template<typename T>
class Foo
{
private:
    void foo()
    {
        std::cout << "Foo<T>::foo()" << std::endl;
    }

public:    
    Foo() : bar( *this , &Foo::foo ) 
    {
        bar();
    }

    Bar<Foo<T> > bar;
};

int main()
{
    Foo<int> foo;
}

This works on MSVC 2013 and GCC 4.8.3. Is it valid?


回答1:


Yes it is permissible, and it works.

C++ Programming by Bjarne Stroustoup

C++ protects against accident rather than deliberate circumvention (fraud)

Sure, you cannot directly/easily call private methods outside the class, but if you are making enough efforts, C++ will allow it.




回答2:


C++ standard says

11.1 A member of a class can be
(1.1) — private; that is, its name can be used only by members and friends of the class in which it is declared.

i.e. the access specifier is applied to the name, not the executable code. This makes sense if you think about it, since access specifiers are a compile-time construct.




回答3:


Yes, it is valid.

Bar.operator()() is just using a pointer, not trying to use an identifier with private access specifier.
It does not matter how that pointer was initialized, as long as it points to the right function.

As an example, look at this:

#include <iostream>
struct A {
protected:
    void hidden() { std::cout << "But I was hidden !?\n"; }
};
struct B : A {
    using A::hidden; // Making it public
};
int main() {
    B().hidden();
}

As an aside, don't use std::endl unless you really want to flush the stream, as that's expensive.
Normally '\n' suffices.




回答4:


It does matter.

Header File

class A;
typedef int (A::*handler)(int x);
struct handler_pair {
    int code,
    handler fn
}

class A {
...
private:
  int onGoober(int x);
  int onGomer(int x);
};

Source file

handler_pair handler_map[] = {
    {0, &A::onGoober},          // these will complain about the method being private
    {1, &A::onGomer}
};

Changing the handler_map to a static member in the class and initializing that way avoids the complaint.

Where you take the address of the member function is important.



来源:https://stackoverflow.com/questions/27537482/able-to-use-pointer-to-function-to-call-private-method-of-an-external-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!