繁体   English   中英

错误:C++ 中派生的受保护结构无法访问函数

[英]error: function is inaccessible for derived protected Struct in C++

我有

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

我不明白这些错误。 因为B继承自A是受保护的,所以它不应该可以访问Ohai吗? 当我将继承更改为public ,我没有出错

编辑: 私有、公共和受保护继承之间的区别不能回答我的问题。 根据该链接, B应根据受保护的继承继承ohai

关于privateprotectedprivate的关键是了解一个类及其后代是否理解一个类正在对某些东西进行子类化,而不是类的外部代码是否理解它是否正在对某些东西进行子类化。

假设我们从A类开始:

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

现在Bprotected子类A 这意味着B及其继承者明白BA一种类型。 实际上,请注意在foo方法中, this是如何转换为A *

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

现在Cpublic子类B 注意它是如何知道它是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方法。

这是因为您将 A 声明为私有的:

Struct C : private A{}

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

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

但是, main()不在类B或从B派生的类的范围内,因此不允许main()调用B().ohai()

访问检查重要的是您正在调用的函数,而不是您正在调用的对象。

您不能直接从外部访问私有和受保护的数据或功能。 为此,您需要在公共范围内拥有一个 Getter。

B 有 A 的副本,因此它具有 ohai() 但在受保护的范围内,因此 B 的对象无法访问 ohai()。 (protected 和 private 不能从外部访问,但只能是公共的)。

所以编写 B().ohai() 会导致编译时错误。

A().ohai(): A 可以访问 ohai() 因为 ohai 是公共范围的,默认情况下记住结构它们对成员具有公共访问权限,这与默认情况下是私有的类不同。

C:从 A 私有继承,因此 A() 的所有成员(公共、受保护、私有)都将在结构 C 中的私有范围内,因此如果您编写尝试访问其中之一将出现错误:尝试访问私有数据。 但是 main() 被声明为 C 的友元,因此它可以访问 C 私有、受保护和公共的所有成员。 (friend 函数可以完全访问它们被声明为朋友的所有成员)例如

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

D:从 B 公开继承所以 B 的所有成员 EXCEPT private 都在 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 中都是私有的,因此 C 中从 A 继承的所有这些成员都不会被继承。 所以 E 不能访问 ohai() 因为它是在 C 中私下继承的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM