Re: C2248: cannot access protected member



Alex Blekhman <tkfx.REMOVE@xxxxxxxxx> wrote:
class X
{
protected:
void foo() {}
int a;
};

class Y : public X
{
public:
void bar()
{
X::foo(); // OK
int b = X::a; // OK

void (X::*pf)() = &X::foo; // error C2248!
int X::*pa = &X::a; // error C2248!
}
};

All compilers emit C2248 error or equivalent. I want to understand
why this happens. Why accessing protected members is OK while
taking their pointers is an error?

The short answer is that the C++ standard says so:

11.5/1 When a friend or a member function of a derived class references
a protected nonstatic member of a base class, an access check applies in
addition to those described earlier in clause 11. Except when forming a
pointer to member (5.3.1), the access must be through a pointer to,
reference to, or object of the derived class itself (or any class
derived from that class) (5.2.5). If the access is to form a pointer to
member, the nested-name-specifier shall name the derived class (or any
class derived from that class).

So &X::foo fails the access check, but &Y::foo works.

Here's the long answer. Class Y is presumed to know how it uses
protected members of its base class X, and can access them freely. But
it doesn't necessarily know how some other class Z derived from X might
use X's protected members, and is not allowed to mess up with those.
Consider:

class Z : public X {};

void Y::baz(Z* pz) {
X::foo(); // fine - calls foo() on itself
pz->X::foo(); // doesn't compile - calls foo on Z

int b = X::a; // fine - access its own members
b = pz->X::a; // doesn't compile
}

If &X::foo worked inside Y, baz() could have worked around the
restrictions like this:

void Y::baz(Z* pz) {
void (X::*pf)() = &X::foo; // hypothetical, doesn't compile
(pz->*pf)(); // same as pz->foo()
}

--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


.



Relevant Pages

  • Re: Virtual Data?
    ... > pointer to function. ... type of data for a member variable of the same name, ... But your derived class needs a more complicated variable x, ... virtual Init(const int initX); ...
    (comp.lang.cpp)
  • Re: executing a member function in a separate thread
    ... pointer, but behind this pointer can be an arbitrary large portion of data). ... If you want to invoke a member function on some object, you need to write something like the following: ... void someMethod; ... void someMethodInOwnWorkerThread; ...
    (microsoft.public.vc.language)
  • Answered?: Accessing a protected member of a member of type BaseClass????
    ... A protected nonstatic base class member can be accessed by members and ... * A reference to a directly or indirectly derived class ... friend void f; ...
    (comp.lang.cpp)
  • Re: C2248: cannot access protected member
    ... 11.5/1 When a friend or a member function of a derived class references ... pointer to member, the access must be through a pointer to, ... protected members of its base class X, ...
    (microsoft.public.vc.language)
  • Re: Pointer to a member variable in a struct without dereferencing the member
    ... I have the below struct and I need to access the pointer to the "void ... * data" member without actually dereferencing the member variable. ...
    (comp.lang.c.moderated)

Loading