c++ - 无法从派生类型的范围访问另一个实例的 protected 成员

标签 c++ language-lawyer encapsulation protected

this answer对于“为什么我的对象不能访问公共(public)基类中定义的另一个对象的 protected 成员?”这个问题,可以阅读:

You can only access protected members from your own base class instance.

要么是我没有理解正确,要么是 following MCVE (live on coliru)证明是错误的:

struct Base           { void f(); protected: int prot; };
struct Derived : Base { void g(); private:   int priv; };

void Base::f()
{
    Base b;
    b.prot = prot;
    (void) b;
}

void Derived::g()
{
    {
        Derived d;
        (void) d.priv;
    }

    {
        Derived& d = *this;
        (void) d.priv;
    }

    {
        Derived d;
        (void) d.prot; // <-- access to other instance's protected member
    }

    {
        Derived& d = *this;
        (void) d.prot;
    }

    // ---

    {
        Base b;
        (void) b.prot; // error: 'int Base::prot' is protected within this context
    }

    {
        Base& b = *this;
        (void) b.prot; // error: 'int Base::prot' is protected within this context
    }
}

鉴于这两个错误,我想知道:为什么我可以从 Derived 的范围访问另一个 Derived 实例的 protected 成员,但不能访问另一个 Base 实例的 protected 成员来自同一范围,而不管 DerivedBase 偏离的事实? ;博士:在这种情况下,是什么让 protectedprivate 更“私密”?

注释:

  • 请不要将此问题作为链接问题的拷贝来关闭;
  • 欢迎提出更好的标题建议。

最佳答案

[class.access.base] 中的规则是:

A member m is accessible at the point R when named in class N if [...]

  • m as a member of N is protected, and R occurs in a member or friend of class N, or in a member of a class P derived from N, where m as a member of P is public, private, or protected

里面有很多字母。但基本上有两个条件:

  1. R 是类(class)的成员或 friend 。这处理 d.prot 示例 - 我们在 Derived 的成员中访问 Derived 的 protected 成员。
  2. R 在派生类的成员中,被访问的成员派生类实例的成员。这处理了 b.prot 示例 - 我们是派生类的成员,但 prot 不是派生类的成员。

换句话说,Derived 可以访问Base 的 protected 成员——但前提是它正在访问它自己的子对象的 protected 成员。它不能访问其他 Base 对象的 protected 成员。当您认为这个其他 Base 很容易成为 SomeOtherDerived 时,这是有道理的,在这种情况下,这只是我们没有特殊访问权限的另一个不相关的对象。

关于c++ - 无法从派生类型的范围访问另一个实例的 protected 成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45146025/

相关文章:

c++ - 什么时候私有(private)构造函数不是私有(private)构造函数?

c# - 在可重用类中封装多个服务引用操作

c++ - 使用 Visual Studio 2015 : error C3546 在 lambda 中扩展参数包

c++ - 空 vector <...> 没有名为的成员

c++ - 了解 C++ 中的指针初始化行为

c++ - 为什么找不到用命名空间中定义的类型实例化的 std::weak_ptr 的重载运算符==?

c++ - 如何使用 C++ 从 OMNet++ 中的 cModule 获取 cSimpleModule?

c++ - 关于在 vector 上调用 clear 如何改变容量的标准说明了什么?

c# - 是否可以限制 C# 中的公共(public)枚举值?

Java:按钮封装