【问题标题】:What's the reason for protected member accessibility additional check in C++?C++ 中受保护的成员可访问性附加检查的原因是什么?
【发布时间】:2013-11-17 05:04:20
【问题描述】:

我刚刚遇到这个问题,并且从 C++ 标准中知道它的定义如下(强调我的)

除前面第 11 条所述之外的附加访问检查 在非静态数据成员或非静态成员函数时应用 是其命名类 (11.2)115 的受保护成员,如所述 早些时候,授予对受保护成员的访问权限,因为引用 发生在某个 C 类的朋友或成员中。如果访问要形成 指向成员 (5.3.1) 的指针,嵌套名称说明符应表示 C 或从 C 派生的类。所有其他访问都涉及(可能 隐式)对象表达式(5.2.5)。 在这种情况下, 对象表达式应为 C 或从 C 派生的类。

代码sn-p:

class Base
{
protected: 
    int i;
};

class Derived : public Base
{
public:
    // I cannot define it as void memfunc(Derived* obj) because of signature requirement.
    void memfunc(Base* obj) 
    {
       obj->i = 0;  // ERROR, cannot access private member via Base*
       Derived* dobj = (Derived*)(obj);
       dobj->i = 0; // OK
    }
};

那么这次检查的原因是什么?为什么 C++ 标准要通过基类指针来限制访问受保护的成员?

Not Duplicate to:Accessing protected members in a derived class,我想问一下标准中禁止它的原因。

【问题讨论】:

    标签: c++


    【解决方案1】:

    仅仅因为您从Base 派生并不意味着您应该被允许访问从Base 派生的任何其他类的受保护成员。想象一个类Derived2 由继承自Base 的库提供。这样,您将能够获得Derived2 的基础对象,并在Derived 的代码中使用它做任何您想做的事情。

    因此,基本上该标准确保您只修改您继承的受保护成员,而不会弄乱不相关的兄弟类的完整性。

    【讨论】:

    • 请注意,当obj 实际上指向Derived2 时,问题中的“解决方法”(转换为Derived)是未定义行为。而且你不能使用dynamic_cast,因为Base 不是多态的。
    猜你喜欢
    • 2013-08-06
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 2017-08-01
    相关资源
    最近更新 更多