派生类无法使用成员指针访问受保护的基类成员。

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

我不理解为什么我的派生类型不能创建指向基类受保护成员的指针。它有权限访问该成员。它可以调用相同作用域的函数。为什么不能创建成员指针?我使用的是gcc 4.1.2,出现了以下错误:

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
1
int Base::* i = &Derived::foo; 顺便说一句,运行正常。 - dyp
我猜禁止这样做的原因与禁止访问另一个类型为“Base”的对象的foo的访问相同;即在Derived::bar中也禁止使用Base b; b.foo = 42; - dyp
或者只需 int *i = &foo; *i = 7;。或者,你知道的,foo = 7; - chris
@chris,我特别想使用成员指针来解决问题。显然,在这个示例代码中它们并不是必需的,但这只是样例代码。在我的实际代码中,我需要一个成员指针。 - Daniel Skarbek
谢谢@dyp的澄清,关于派生类型何时需要的解释。这确实有些道理。 - Daniel Skarbek
1个回答

5

通过反复尝试,我找到了一个有意义的解决方案。即使您指向的是一个基类继承成员,指针仍应该是派生类的成员指针。因此,以下代码可行:

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

如果Base的成员被定义为私有,则会出现预期的访问错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接