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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3247671/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:25:25  来源:igfitidea点击:

Accessing protected members in a derived class

c++

提问by miked

I ran into an error yesterday and, while it's easy to get around, I wanted to make sure that I'm understanding C++ right.

昨天我遇到了一个错误,虽然很容易解决,但我想确保我对 C++ 的理解是正确的。

I have a base class with a protected member:

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

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

This compiles and works just fine. Now I extend Base but still want to use b:

这编译和工作得很好。现在我扩展了 Base 但仍然想使用 b:

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

Note that in this case DoSomethingis still taking a reference to a Base, not Derived. I would expect that I can still have access to that.binside of Derived, but I get a cannot access protected membererror (MSVC 8.0 - haven't tried gcc yet).

请注意,在这种情况下DoSomething,仍然引用 a Base,而不是Derived。我希望我仍然可以访问that.b里面的Derived,但是我收到一个cannot access protected member错误(MSVC 8.0 - 还没有尝试过 gcc)。

Obviously, adding a public getter on bsolved the problem, but I was wondering why I couldn't have access directly to b. I though that when you use public inheritance the protected variables are still visible to the derived class.

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

采纳答案by SLaks

A class can only access protected members of instances of this class or a derived class. It cannot access protected members of instances of a parent class or cousin class.

一个类只能访问此类或派生类的实例的受保护成员。它无法访问父类或表亲类的实例的受保护成员。

In your case, the Derivedclass can only access the bprotected member of Derivedinstances, not that of Baseinstances.

在您的情况下,Derived该类只能访问实例的b受保护成员Derived,而不能访问实例的受保护成员Base

Changing the constructor to take a Derivedinstance will solve the problem.

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

回答by Sergei

protectedmembers can be accessed:

protected可以访问成员:

  • through thispointer
  • or to the same type protected members even if declared in base
  • or from friend classes, functions
  • 通过this指针
  • 或相同类型的受保护成员,即使在 base 中声明
  • 或来自友元类、函数

To solve your case you can use one of last two options.

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

Accept Derived in Derived::DoSomething or declare Derived friendto Base:

接受 Derived::DoSomething 中的 Derived 或声明 Derived friendto 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;
    }
};

You may also consider public getters in some cases.

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

回答by sje397

As mentioned, it's just the way the language works.

如前所述,这只是语言的工作方式。

Another solution is to exploit the inheritance and pass to the parent method:

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

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

回答by James Curran

You have access to the protected members of Derived, but not those of Base(even if the only reason it's a protected member of Derivedis because it's inherited from Base)

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

回答by Martin.Bof

You can try with static_cast< const Derived*>(pBase)->Base::protected_member...

您可以尝试使用static_cast< const Derived*>(pBase)->Base::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)->Base::b;
      d=0;
    }
    void DoSomething(const Base* that)
    {
      b += static_cast<const Derived*>(that)->Base::b;
      d=0;
    }
};

回答by Stiv Zhops

Following the hack for stlI wrote a small code which seems to solve the problem of accessing the protected members in derived class

stl hack之后,我写了一个小代码,它似乎解决了访问派生类中受保护成员的问题

#include <iostream>

class B
{
protected:
    int a;
public:
    void dosmth()
    {
        a = 4;
    }

    void print() {std::cout<<"a="<<a<<std::endl;}
};

class D: private B
{
public:
    void dosmth(B &b)
    {
        b.*&D::a = 5;
    }
};

int main(int argc, const char * argv[]) {

    B b;
    D d;
    b.dosmth();
    b.print();
    d.dosmth(b);
    b.print();

    return 0;
}

Prints

印刷

a=4
a=5

回答by vishnu singh

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

//this will work

回答by user5595410

Use thispointer to access protected members

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

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