Reputation: 5839
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?
Upvotes: 17
Views: 11087
Reputation: 310
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.
Upvotes: 0
Reputation: 760
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.
Upvotes: 21
Reputation: 45704
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.
#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.
Upvotes: 1
Reputation: 9859
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.
Upvotes: 9