#include
class A {
protected:
void foo()
{}
};
class B : public A {
public:
void bar()
{
std::cout << (&A::foo) &
I was curious and tried the following example:
#include <iostream>
using namespace std;
class A {
public:
void foo()
{
}
};
class B : public A {
public:
void bar()
{
printf("%p\n", (&A::foo));
printf("%p\n", (&B::foo));
}
};
int main()
{
B b;
b.bar();
}
Actually, I see that &A::foo == &B::foo, so for protected member of base class you can use derived class member to take address. I suppose in case of virtual functions this will not work
Seems I found the answer. If we could get pointer of member function we can call it for other objects of type A (not this) which is not allowed.
It is not allowed to call protected member function in derived classes for objects other than this. Getting pointer would violent that.
We can do something like this:
#include <iostream>
class A {
protected:
void foo()
{}
};
class B : public A {
public:
void bar()
{
void (A::*fptr)() = &A::foo;
A obj;
(obj.*fptr)();
// obj.foo(); //this is not compiled too.
}
};
int main()
{
B b;
b.bar();
}
B is allowed to access protected members of A as long as the access is performed through an object of type B. In your example you're trying to access foo through A, and in that context it is irrelevant whether B derives from A or not.
From N3337, §11.4/1 [class.protected]
An additional access check beyond those described earlier in Clause 11 is applied when a non-static data member or non-static member function is a protected member of its naming class (11.2) As described earlier, access to a protected member is granted because the reference occurs in a friend or member of some class
C. If the access is to form a pointer to member (5.3.1), the nested-name-specifier shall denoteCor a class derived fromC. All other accesses involve a (possibly implicit) object expression (5.2.5). In this case, the class of the object expression shall beCor a class derived fromC. [Example:class B { protected: int i; static int j; }; class D1 : public B { }; class D2 : public B { friend void fr(B*,D1*,D2*); void mem(B*,D1*); }; // ... void D2::mem(B* pb, D1* p1) { // ... int B::* pmi_B = &B::i; // ill-formed int B::* pmi_B2 = &D2::i; // OK // ... } // ...—end example]
Your example is very similar to the code in D2::mem, which shows that trying to form a pointer to a protected member through B instead of D2 is ill-formed.