Access to protected inherited members

Access to protected inherited members

Post by scott dougla » Sat, 25 Mar 1995 20:29:48



Hello,

(11.5) has the following sentence that has been added since the ARM:

"When a protected member of a base class appears in a <qualified-id> in a
friend or a member function of a derived class, the
<nested-name-specifier> must name the derived class."

I believe that this was added to prevent users from using pointers to
members to get to protected members they are not supposed to get to.  And
I think this is a good goal.  The example changed to show that trying to
do this is now an error.

But by using the term <qualified-id> the following code has become illegal:

struct X { protected: int f(); };
struct Y : public X { int f(); };

int Y::f() { return X::f() + 1; }       // now illegal 'X::f' is a
<qualified-id>

Also previously legal was accessing protected static members using a
<qualified-id>:

struct S { protected: static int i; };
struct T : public S { int f(); };

int T::f(int i) { return i + S::i + 1; }       // now illegal 'S::i' is a
<qualified-id>

Was this indended?  These would remain legal if (11.5) were worded
something like:

(11.5) "When a pointer to a protected non-static member of a base class is
formed using &<qualified-id> in a friend or a member function of a derived
class, the <nested-name-specifier> must name the derived class."

This also would allow pointers to protected static members, which is
consistent with being able to access them directl.  The fully fleshed-out
example would now look like:

class B {
protected:
    int i;
    void mem();
static int st;

Quote:};

class D1 : public B {

Quote:};

class D2 : public B {
    friend void fr(B*,D1*,D2*);
    mem(B*,D1*);

Quote:};

void fr(B* pb, D1* p1, D2* p2)
{
    pb->i = 1;  // illegal
    p1->i = 2;  // illegal
    p2->i = 3;  // ok
    B::st = 4;  // ok
    int B::*  pmi_B = &B::i;    // illegal
    int D2::* pmi_D2 = &D2::i;  // ok
    int*      pi = &B::st;      // ok
    B::mem(pb, p1);  // ok, same as 'mem()'

Quote:}

void D2::mem(B* pb, D1* p1)
{
    pb->i = 1;  // illegal
    p1->i = 2;  // illegal
    i = 3;      // ok (access through 'this')
    B::st = 4;  // ok, same as 'st = 4'
    B::mem(pb, p1);  // ok, same as 'mem()'

Quote:}

void g(B* pb, D1* p1, D2* p2)
{
    pb->i = 1;  // illegal
    p1->i = 2;  // illegal
    p2->i = 3;  // illegal
    B::st = 4;  // illegal
    int B::*  pmi_B = &B::i;    // illegal
    int*      pi = &B::st;      // illegal
    pb->mem(pb, p1); // illegal
    p1->mem(pb, p1); // illegal
Quote:}

       --scott
 
 
 

1. Inherited member access

I assume that the following is still

illegal according to the draft spec:

  class A {public: int a;};
  class B : private A {protected: A::a;};

but is there any plausible reason why? It doesn't take away access to A::a
that users of B would otherwise have, nor does it increase access to A::a
that users of A would otherwise not have. In this respect, it seems very
similar to:

  class B : private A {public: A::a;};

which *is* legal. This is in contrast to:

  class B : public A {protected: A::a;};

whose illegality I'm not questioning.

Regards,
Robin

2. New Print Shop & ALS Parallel Interface Problems

3. 'SetRegistryKey' : cannot access protected member declared in class 'CWinApp'

4. ATSpeed

5. error C2248: 'SetRegistryKey' : cannot access protected member declared in class 'CWinApp'

6. MySQL & MacOS9

7. Access to private and protected members

8. 4SALE: Archive Viper 525 meg tape drive

9. Access of protected members in derived class?

10. HELP: can not access protected members via pointer.

11. Problem: accessing protected members of base class

12. Access to base class protected members

13. protected member access