为什么我们无法使用指向派生类的指针访问受保护的基类成员?

时间:2014-05-09 12:24:19

标签: c++ class inheritance

我已经写了以下代码:

#include <stdio.h>

class A
{
protected:
    void foo()
    {
        printf("class A\n");
    }
};

class B : public A
{
    void bar()
    {
        printf("class B\n");
    }
};

int main()
{
    B *b= new B();
    b->foo();
}

当我编译它时,我发现错误

test.cpp: In function ‘int main()’:
test.cpp:6:7: error: ‘void A::foo()’ is protected
test.cpp:23:9: error: within this context

但是在N3797工作草案中表示

  

保护;也就是说,它的名称只能由声明它的类的成员和朋友使用,来自派生自的类   那个班,还有他们的朋友

  

如果一个类被声明为另一个类的基类(第10条)   class使用公共访问说明符,公共成员   基类可以作为派生类的公共成员访问   受保护的基类的受保护成员可以访问   派生类的成员。

4 个答案:

答案 0 :(得分:4)

您尝试拨打b->foo()的代码是:

  • 不是A
  • 的成员
  • 不是A
  • 的朋友
  • 不是B(唯一派生类型)的成员
  • 不是B
  • 的朋友

因此,在您引用的段落中,它不能使用名称foo

答案 1 :(得分:2)

简单地说:您正试图从外部类层次结构中访问受保护的成员。以下方法可行:

class B : public A
{
    void bar() // bar is "inside" your class hierarchy
    {
        foo(); // compiles
        printf("class B\n");
    }
};

但这不是:

// some code, e.g. in main
b->foo(); // error - "outside" of the class

有关正式解释,请参阅Jon's answer


注意:您的B类可以成为protected成员public,如下所示:

class B : public A
{
public:
    // This adds a public foo to B, which invokes the protected foo from A
    void foo()
    {
        A::foo(); 
    }
};

这样,只要您使用B指针/实例/引用,您的示例就可以正常工作。

答案 2 :(得分:0)

B,而不是main,可以访问A个成员。

选项:

  1. foo()公开,而不是受保护
  2. B内设置一个名为foo()的公开方法并将其调用。

答案 3 :(得分:0)

main开始,您只需访问B中定义的或继承自A的public members of B