首页 文章

访问派生类中的受保护成员

提问于
浏览
47

我昨天遇到了一个错误,虽然很容易绕过,但我想确保我理解C正确 .

我有一个受保护成员的基类:

class Base
{
  protected:
    int b;
  public:
    void DoSomething(const Base& that)
    {
      b+=that.b;
    }
};

这编译并且工作得很好 . 现在我扩展Base但仍想使用b:

class Derived : public Base
{
  protected:
    int d;
  public:
    void DoSomething(const Base& that)
    {
      b+=that.b;
      d=0;
    }
};

请注意,在这种情况下, DoSomething 仍然引用 Base ,而不是 Derived . 我希望我仍然能够访问 Derived 内的 that.b ,但是我得到 cannot access protected member 错误(MSVC 8.0 - 还没有尝试过gcc) .

显然,在 b 上添加公共getter解决了这个问题,但我想知道为什么我无法直接访问 b . 我认为,当您使用公共继承时,受保护的变量对派生类仍然可见 .

7 回答

  • 0

    您只能访问类型实例中的受保护成员(或从您的类型派生) .
    您无法访问父级或堂兄类型的实例的受保护成员 .

    在您的情况下, Derived 类只能访问 Derived 实例的 b 成员,而不能访问不同的 Base 实例 .

    更改构造函数以获取 Derived 实例也将解决此问题 .

  • 3

    您可以访问 Derived 的受保护成员,但不能访问 Base 的成员(即使它是 Derived 的受保护成员的唯一原因是因为它继承自 Base

  • -3

    如上所述,它只是语言的工作方式 .

    另一种解决方案是利用继承并传递给父方法:

    class Derived : public Base
    {
      protected:
        int d;
      public:
        void DoSomething(const Base& that)
        {
          Base::DoSomething(that);
          d=0;
        }
    };
    
  • 3

    可以访问 protected 成员:

    • 通过 this 指针

    • 或相同类型的受保护成员,即使在base中声明

    • 或来自朋友类,函数

    要解决您的情况,您可以使用最后两个选项之一 .

    接受Derived :: DoSomething中的Derived或将Derived friend 声明为Base:

    class Derived;
    
    class Base
    {
      friend class Derived;
      protected:
        int b;
      public:
        void DoSomething(const Base& that)
        {
          b+=that.b;
        }
    };
    
    class Derived : public Base
    {
      protected:
        int d;
      public:
        void DoSomething(const Base& that)
        {
          b+=that.b;
          d=0;
        }
    };
    

    在某些情况下,您也可以考虑使用公共吸气剂 .

  • 37
    class Derived : public Base
    {
      protected:
        int d;
      public:
        void DoSomething()
        {
          b+=this->b;
          d=0;
        }
    };
    
    //this will work
    
  • 1

    你可以试试 static_cast< const Derived>(pBase)->protected_member* ......

    class Base
    {
      protected:
        int b;
    
      public:
        ...
    };
    
    class Derived : public Base
    {
      protected:
        int d;
    
      public:
        void DoSomething(const Base* that)
        {
          b += static_cast<const Derived*>(that)->b;
          d=0;
        }
    };
    
  • 1

    使用 this 指针访问受保护的成员

    class Derived : public Base
    {
      protected:
        int d;
      public:
        void DoSomething(const Base& that)
        {
          this->b+=that.b;
          d=0;
        }
    };
    

相关问题