错误:C ++中派生的受保护Struct不能访问函数

时间:2016-09-30 15:50:23

标签: c++

我有

Firefox for Android Artifact Mode

然而,我得到了错误

struct A { void ohai() {} };

struct B: protected A {};

struct C: private A { friend int main();};

struct D: B { void test() { ohai();} };

struct E: C { void test() { ohai();} };

int main() {
    A().ohai();
    B().ohai();
    C().ohai();
    D().ohai();    
    return 0;
}

我不明白这些错误。由于error: ‘void A::ohai()’ is inaccessible struct A { void ohai() {} }; ^ main.cpp:20:11: error: within this context B().ohai(); ^ main.cpp:8:17: error: ‘void A::ohai()’ is inaccessible struct A { void ohai() {} }; ^ main.cpp:22:11: error: within this context D().ohai(); 的{​​{1}}继承受到保护,是否应该有权访问B?当我将继承更改为A时,我没有错误

编辑:Difference between private, public, and protected inheritance没有回答我的问题。根据该链接,Ohai应根据受保护的继承继承public

4 个答案:

答案 0 :(得分:1)

关于privateprotectedprivate的关键是理解一个类及其后代是否理解一个类是子类化的东西,而不是类的外部代码是否理解是否它是子类化的东西。

假设我们从课程A开始:

struct A {
    void ohai() {};
};

现在B子类Aprotected。这意味着B及其继承人理解BA的一种类型。确实,请注意foo方法中this如何转换为A *

struct B : protected A {
    void foo() {
        A *a = this;
    }
};

现在C子类Bpublic。请注意它是如何知道它是A的类型(因为它知道它是B的类型,它知道BA的类型。我们可以在其bar方法中再次看到它:

struct C : public B {
    void bar() {
        A *a = this;
    }
};

最后,D子类A公开:

struct D : public A {
};

到目前为止,我们已经考虑了课程内容的外观。现在让我们看看它们在外面的样子。

我们继续说:

int main() {
    A *p;

    A a;
    B b;
    D d;

然后,当然,p可以指向&a

    p = &a;

自公共D子类A起,它也可以指向&d

    p = &d;

但是,由于B子类A受保护,因此它不知道它是它的子类。以下行未能编译:

    p = &b;
}

因此导致您的错误 - 它不知道它是它的子类,因此从侧面不知道它有ohai方法。

答案 1 :(得分:0)

这是因为您声明A是私人的:

Struct C : private A{}

这使得A完全私有,因此所有结构都无法接受C.

答案 2 :(得分:0)

由于受保护的继承,函数A::ohai()可以访问类B和从B派生的类。这就是允许D::test()访问ohai的原因。

但是,main()不属于班级B或源自B的班级,因此main()不允许调用B().ohai()

访问检查的重点是您正在呼叫的功能,而不是您正在呼叫的对象。

答案 3 :(得分:0)

您无法直接从outisde访问私有和受保护的数据或函数。要做到这一点,你需要在公共范围内拥有一个Getter。

B有A的副本,所以它有ohai()但在受保护的范围内,因此B的对象无法访问ohai()。 (受保护和私人无法从外部访问,但只能公开)。

所以写B()。ohai()将发出编译时错误。

A()。ohai():A可以访问ohai(),因为ohai是公共范围的记住结构,默认情况下他们可以公开访问成员,而不像默认的私有类。

C:从A私下继承,所以A()(public,protected,private)的所有成员都将在struct C的私有范围内,所以如果你写的尝试访问其中一个将发出错误:尝试访问私人数据。但是main()被声明为C的朋友,因此它可以访问C private,protected和public的所有成员。 (朋友功能可以完全访问他们被宣布为朋友的所有成员),例如

friend ostream& operator << (ostream&, myClass &rhs); // this function can access all members of myClass

D:从B公开继承所以B EXCEPT私有的所有成员都将在D中(记住私有成员不被继承)并且B从A继承受保护,因此B不能直接访问ohai()(保护)因此D无法访问ohai()因为B中的ohai()受到保护。

如果你写:

D().test();// it's ok because test() in D is public and test() is a member of D so it can access ohai();

E:从C公开继承,因此E可以访问C中的所有内容但是私有,C从A私下继承,因此A的所有成员在c中都是私有的,因此从A继承的C中的所有这些成员都不会被继承。所以E无法访问ohai(),因为它是在C中私下继承的。