#include <iostream>
class A {
protected:
void foo()
{}
};
class B : public A {
public:
void bar()
{
std::cout << (&A::foo) << std::endl;
}
};
int main()
{
B b;
b.bar();
}
Here I am trying to get address of protected member function of base class. I am getting this error.
main.cpp: In member function ‘void B::bar()’:
main.cpp:5: error: ‘void A::foo()’ is protected
main.cpp:13: error: within this context
make: *** [all] Error 1
Changing foo to public works. Also printing &B::foo
works. Can you please explain why we can't get address of protected member function of base class?
protected members are not accessible in derived classes.
If a class is derived privately from a base class, all protected base class members become private members of the derived class. Class A contains one protected data member, an integer i . Because B derives from A , the members of B have access to the protected member of A .
Create a public function that calls the protected one. This can be accomplished through either deriving Test or creating another class, Test2, and declaring Test a friend of Test2 and having Test2 contain an instance of Test. Seeing all the instructions of your homework would help.
B. Friend function can access protected data members of the class.
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 denoteC
or 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 beC
or 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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With