【问题标题】:Accessing protected members for other than "this" object [duplicate]访问“this”对象以外的受保护成员[重复]
【发布时间】:2014-04-24 09:30:39
【问题描述】:

我一直以为我知道protected 是什么意思。这里也有一个很好的解释:Private and Protected Members : C++。 我将其理解为:每当我处于派生类的上下文中时,我都可以调用其基类的受保护成员。

在下面的代码中,我试图在派生类中调用受保护的方法,但它是在另一个继承分支中的另一个对象上调用的。由于某种原因,这会导致错误(在 g++ 和 clang++ 中都尝试过)。

#include <iostream>

class A {
    protected:
        void foo() {
            std::cout << "Hello world!\n";
        }
};

class B : public A {
};

class C : public A {
    public:
        void bar(B* other) {
            foo(); //OK
            other->foo(); //Error
        }
};

int main() {
    return 0;
}

所以我的问题是:究竟受保护成员的规则是什么?它最近是否随着新的 C++ 标准而改变?

【问题讨论】:

  • “受保护成员的确切规则是什么?”如果您想要确切的规则,请阅读标准。 “它最近是否随着新的 C++ 标准而改变?”没有。

标签: c++ access-modifiers


【解决方案1】:

每个人都需要一个朋友!

班级也不例外:当他们需要分享大大小小的秘密(私人的或受保护的)时,他们需要知道他们有一个朋友。只需在您的 A 类中添加一行,说明 C 是朋友将允许访问否则无法访问的成员和函数:

friend class C;

紧接在foo() 函数的最后一个} 之后将允许C 访问。

This link at cplusplus.com 将有助于提供有关朋友类的更多详细信息,但在大多数情况下,如果您发现自己不得不经常授予朋友身份,则可能需要重新考虑继承层次结构。

这是您与朋友的源代码的修改版本:

#include <iostream>

class A {
    protected:
        void foo() {
            std::cout << "Hello world!\n";
        }
        friend class C;
};

class B : public A {
};

class C : public A {
    public:
        void bar(B* other) {
            foo(); //OK
            other->foo(); //no error if A and C are friends
        }
};

int main() {
    B* b = new B();
    C* c = new C();
    c->bar(b);
    return 0;
}

如果您需要更多信息,请告诉我:)

附录: 发生错误是因为您有一个间接层,而 B 或 C 可以从其直接祖先 A 访问受保护的方法,但它们无法通过另一个类的实例访问它,因为在该级别上,受保护的成员是所有意图和私人用途:

Class A    ---    protected foo()
Class B    ---    inherits from A: foo() effectively private at B level
Class C    ---    inherits from A: foo() effectively private at C level
           ---    bar() method calls instance of B to provide access to foo() via B
                  however this is not valid because foo() is private for B, 
                  therefore C cannot call it
           ---    also has its own call to foo(): Valid call to its own private function

希望这能更清楚地了解可见性在不同级别的工作方式,今晚回家后我会查找一些参考资料并访问我的书籍。

【讨论】:

  • 'friend' 是对隐私的替代,我很清楚该解决方案,但它根本没有回答问题 - 为什么会发生错误。
  • @CygnusX1 我已经更新了答案以包括为什么 b-&gt;foo() 不能从类 C 的实例中获得。
  • “有效私有”即使没有错也完全不清楚。如果您有继承A-&gt;B-&gt;C-&gt;D,您仍然可以访问 D 中 A 的受保护方法。阅读副本中的答案 - 他们很好地回答了问题,尽管起初措辞不清楚。
  • 我同意你的观点,但是在这种情况下继承是 A->B 然后 A->C; B 是 C 的兄弟,因此 B 的受保护成员就 C 而言实际上是私有的,反之亦然。如果 C 是 B 的子类,那么就没有问题,只是它们位于继承树的不同分支上:子类保持受保护成员的可见性,而兄弟类则不然。 (是的,我知道我正在混合语言私有和 C++ private 但是我想不出更简洁的方式来表达它。我将重新考虑并重新发布:)看看我是否可以让它更简洁。
猜你喜欢
  • 1970-01-01
  • 2016-01-07
  • 2011-03-29
  • 2012-05-26
  • 2012-11-20
  • 1970-01-01
  • 2017-08-01
  • 2016-10-01
相关资源
最近更新 更多