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

时间:2022-09-20 15:54:44

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:

这将编译并正常工作。现在我扩展基数,但仍然想用b:

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

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

注意,在这个例子中DoSomething仍然在引用一个基,而不是派生的。我希望我还能接触到它。b在导出内部,但我得到a无法访问受保护的成员错误(MSVC 8.0 -还没有尝试gcc)。

Obviously, adding a public getter on b solved 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.

显然,在b上添加公共getter解决了这个问题,但是我想知道为什么我不能直接访问b。

6 个解决方案

#1


36  

You can only access protected members in instances of your type (or derived from your type).
You cannot access protected members of an instance of a parent or cousin type.

您只能在类型的实例(或从类型派生)中访问受保护的成员。不能访问父类或表类实例的受保护成员。

In your case, the Derived class can only access the b member of a Derived instance, not of a different Base instance.

在您的例子中,派生类只能访问派生实例的b成员,而不能访问不同的基本实例。

Changing the constructor to take a Derived instance will also solve the problem.

更改构造函数以获取派生实例也将解决这个问题。

#2


3  

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 Derived is because it's inherited from Base)

您可以访问派生的受保护成员,但不能访问基础的成员(即使它是派生的受保护成员的惟一原因,因为它是从基础继承的)

#3


3  

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;
    }
};

#4


1  

protected members can be accessed:

可访问受保护成员:

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

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

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

Accept Derived in Derived::DoSomething or declare Derived friend to Base:

接受派生的:::DoSomething或声明派生的朋友到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.

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

#5


1  

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

//this will work

#6


-2  

Use this pointer to access protected members

使用此指针访问受保护成员

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

#1


36  

You can only access protected members in instances of your type (or derived from your type).
You cannot access protected members of an instance of a parent or cousin type.

您只能在类型的实例(或从类型派生)中访问受保护的成员。不能访问父类或表类实例的受保护成员。

In your case, the Derived class can only access the b member of a Derived instance, not of a different Base instance.

在您的例子中,派生类只能访问派生实例的b成员,而不能访问不同的基本实例。

Changing the constructor to take a Derived instance will also solve the problem.

更改构造函数以获取派生实例也将解决这个问题。

#2


3  

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 Derived is because it's inherited from Base)

您可以访问派生的受保护成员,但不能访问基础的成员(即使它是派生的受保护成员的惟一原因,因为它是从基础继承的)

#3


3  

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;
    }
};

#4


1  

protected members can be accessed:

可访问受保护成员:

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

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

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

Accept Derived in Derived::DoSomething or declare Derived friend to Base:

接受派生的:::DoSomething或声明派生的朋友到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.

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

#5


1  

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

//this will work

#6


-2  

Use this pointer to access protected members

使用此指针访问受保护成员

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