4
include <stdio.h>

class Base
{
protected:
    int foo;
    int get_foo() { return foo; }
};

class Derived : public Base
{
public:
    void bar()
    {
        int Base::* i = &Base::foo;
        this->*i = 7;
        printf("foo is %d\n", get_foo());
    }
};


int main()
{
    Derived d;
    d.bar();
}

I don't understand why my derived type can't make a pointer to the protected member of the base class. It has privilege to access the member. It can call the similarly scoped function. Why can't it make a member pointer? I'm using gcc 4.1.2 and I get this error:

test.cc: In member function ‘void Derived::bar()’:
test.cc:6: error: ‘int Base::foo’ is protected
test.cc:15: error: within this context
Daniel Skarbek
  • 554
  • 4
  • 14
  • BTW, if I add a friend declaration this works just fine, but that seems odd to me to declare my derived class as a friend when I am only trying to access a protected member that I should have access to already. – Daniel Skarbek Jul 21 '14 at 16:04
  • 1
    `int Base::* i = &Derived::foo;` works fine btw. – dyp Jul 21 '14 at 16:04
  • I guess the reason to forbid this is the same as forbidding the access to `foo` of another object of type `Base`; i.e. `Base b; b.foo = 42;` is also forbidden inside `Derived::bar`. – dyp Jul 21 '14 at 16:07
  • Or just `int *i = &foo; *i = 7;`. Or, you know, `foo = 7;` – chris Jul 21 '14 at 16:08
  • @chris, I'm specifically, looking for a solution using member pointers. Obviously they are not necessary to this sample code, but this is just sample code. In my actual code, I need a member pointer. – Daniel Skarbek Jul 21 '14 at 16:37
  • Thanks @dyp, for the clarification on where the Derived type is needed. That does make some sense. – Daniel Skarbek Jul 21 '14 at 16:39

1 Answers1

5

By trial and error I found a solution that makes some sense. Even if it is a base class inherited member that you are pointing to, the pointer should still be a member pointer of the Derived class. So, the following code works:

include <stdio.h>

class Base
{
protected:
    int foo;
    int get_foo() { return foo; }
};

class Derived : public Base
{
public:
    void bar()
    {
        int Derived::* i = &Derived::foo;
        this->*i = 7;
        printf("foo is %d\n", get_foo());
    }
};

int main()
{
    Derived d;
    d.bar();
}

If Base's members are scoped as private then you get the expected lack of access error.

Daniel Skarbek
  • 554
  • 4
  • 14