c++ - 为什么派生类不能在这段代码中调用 protected 成员函数?

标签 c++ oop

#include <iostream>

class Base
{  
protected:
    void somethingProtected()
    {
        std::cout << "lala" << std::endl;
    }
};

class Derived : public Base
{
public:
    void somethingDerived()
    {
        Base b;
        b.somethingProtected();    // This does not compile
        somethingProtected();      // But this is fine
    }
};

int main()
{
    Derived d;
    d.somethingDerived();
    return 0;
}

我想也许只有 this 的 protected 成员可以使用,而其他实例的 protected 成员永远无法访问。

但是:

class Derived : public Base
{
public:

    void somethingDerived(Derived& d)
    {
        d.somethingProtected();  // This compiles even though d is
                                 // potentially a different instance
    }

    void somethingDerived(Base& b)
    {
        b.somethingProtected();  // This does not
    }
};

我对此感到有点恶心,因为我已经用 C++ 编程了一段时间,但我找不到任何解释这种行为的原因。

编辑:

不管是同一个还是不同的实例:

int main()
{
    Derived d1, d2;          // Two different instances
    d1.somethingDerived(d2); // This compiles fine
    d1.somethingDerived(d1); // This compiles fine
    return 0;
}

EDIT2:

似乎在访问权限方面,使用什么类的实例并不重要:

class Base
{
public:
    void something(Base& b)  // Another instance
    {
        ++b.a;               // But can enter private members
    }

private:
    int a;
};

最佳答案

尽管 C++ 中的访问控制是基于每个类(而不是基于每个实例)工作的,但 protected 访问说明符有一些特殊性。

语言规范希望确保您访问的是属于派生类的某个基本子对象的 protected 成员。您不应该能够访问一些不相关的基本类型独立对象的 protected 成员。特别是,您不能访问基本类型的 独立 对象的 protected 成员。您只能访问作为基础子对象嵌入派生对象中的基础对象的 protected 成员。

因此,您必须通过 pointer->member 语法、reference.memberobject.member 语法来访问 protected 成员,其中指针/引用/对象指的是派生类。

这意味着在您的示例中, protected 成员 somethingProtected() 无法通过 Base 对象、Base * 指针或 访问基础 & 引用,但可以通过 Derived 对象、Derived * 指针和 Derived & 引用访问。您的普通 somethingProtected() 访问是允许的,因为它只是 this->somethingProtected() 的简写,其中 this 的类型是 派生*

b.somethingProtected() 违反了上述要求。

注意按照上面的规则在

void Derived::somethingDerived()
{
    Base *b = this;
    b->somethingProtected();    // ERROR
    this->somethingProtected(); // OK
}

第一个调用也将失败,而第二个调用将编译,即使两者都试图访问同一个实体。

关于c++ - 为什么派生类不能在这段代码中调用 protected 成员函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16785069/

相关文章:

c++ - 类成员值的合法或错误成员使用?

c# - 检查子类是否属于特定类型的最佳方法是什么?

c# - C# 中具有抽象子类的基类?

javascript - 为什么它显示为未定义/NaN?

c++ - 如何将 Ubuntu 11 中的 Eclipse Indigo 链接到 C++ 的 FFMPEG 8

c++ - wxMenuItem 加速器规范

c++ - 在嵌套类中声明固定长度的数组

c++ - 二叉搜索树

c++ - 从 C 到 C++

XCode : in defining operator* "no viable overloaded operator *=" while *= has been tested and is functional 中的 C++ 错误