Why is it impossible to get a pointer to a protected method of a base class?

class A { public: A() {auto tmp = &A::foo;} protected: void foo() {} }; class B : public A { public: B() {auto tmp = &A::foo;} }; 

Class A not a problem. Class B gives a compilation error:

'A :: foo': cannot access the protected member declared in class 'A'

Why is this, what is the rationale? Is there any way around this (if I need this pointer for a callback, std::function , etc.)?

+7
c ++ inheritance
source share
4 answers

If you could take a pointer to A::foo , you can use it to call foo object of type A or type C obtained from A :

 class B : public A { public: void xx(A a) { auto tmp = &A::foo; a.*tmp(); } // illegal } 

Instead, take a pointer to B::foo ; this is great because you can only use it on objects of type B , your own class.

+2
source share

Why is this, what is the rationale?

In general, a derived class can only access protected members of the same derived class, and not to the base class itself or to arbitrary classes with the same base class. Thus, B can access protected members of A through B , but not directly through A

Is there any way around this?

The inherited member is also a member of B and can be accessed as such:

 auto tmp = &B::foo; 
+4
source share

Presumably for security. If you could get a pointer to this member and pass it to absolutely anyone without some kind of alarm, this would be risky.

Here's a workaround (others may know better):

 class A { public: A() {auto tmp = &A::foo;} protected: void foo() {} }; class B : public A { public: B() {auto tmp = &B::foo;} }; 

EDIT - Thought you might need to use A :: foo, but you don't even need to. It works without. Cm:

Accessing a method pointer to a protected method?

+1
source share

You can access it through B , that is:

 class B : public A { public: B() {auto tmp = &B::foo;} }; 

You cannot access &A::Foo from outside B because it is protected, but you can through inheritance (since Foo becomes a member of B through inheritance), that is, by calling &B::Foo

+1
source share

All Articles