Re: C2248: cannot access protected member




"Doug Harrison [MVP]" <dsh@xxxxxxxx> wrote in message
news:3td4q35lnijrv5top8i9m712d7ohr3r1c3@xxxxxxxxxx
On Thu, 31 Jan 2008 14:14:15 -0500, "Igor Tandetnik" <itandetnik@xxxxxxxx>
wrote:

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()
}

I was thinking the same thing, but it doesn't seem like the compiler would
let you say the following even if the hypothetical initialization worked:

(pz->*pf)();

Of course it would, pf was declared as a pointer-to-member of any X


for the same reason it doesn't allow:

pz->foo();

That's why the initialization fails, because baz isn't allowed to call foo
on any X, which is part of the type for pf.


However, it would let you say:

(this->*pf)();

which is potentially useful in a limited way. Am I missing something?

--
Doug Harrison
Visual C++ MVP


.



Relevant Pages

  • Re: C2248: cannot access protected member
    ... void foo() ... 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, ...
    (microsoft.public.vc.language)
  • Re: why cant derived class pointer cant point to base class object
    ... a base class pointer can to point to derived class ... You can implicitly cast pointers to a base class, ...
    (comp.lang.cpp)
  • Re: inheritance
    ... > constructors of a base class are not also members of the derived class. ... side is _converted_ to A* using the standard "pointer to derived to pointer ... to base" conversion. ...
    (comp.lang.cpp)
  • Base class method that returns a pointer to a derived class?
    ... I want to write a base class that includes a member function that creates an ... instance of a derrived class and returns a pointer to it. ... The derived class definition has to follow the base class ...
    (comp.lang.cpp)
  • Re: "this" and "base"
    ... compiler and the programming language. ... a private inherited field in a base class from a derived class is that the ... > because the member "is a private". ...
    (microsoft.public.dotnet.languages.csharp)

Loading