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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9139824/
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-27 12:21:58  来源:igfitidea点击:

How to access protected members in a derived class?

c++inheritance

提问by Aquarius_Girl

From http://www.parashift.com/c++-faq-lite/basics-of-inheritance.html#faq-19.5

来自http://www.parashift.com/c++-faq-lite/basics-of-inheritance.html#faq-19.5

A member (either data member or member function) declared in a protected section of a class can only be accessed by member functions and friends of that class, and by member functions and friends of derived classes

在类的受保护部分中声明的成员(数据成员或成员函数)只能由该类的成员函数和朋友以及派生类的成员函数和朋友访问

So, what is the way to access the protected function funin the derived class?

那么,fun在派生类中访问protected函数的方式是什么?

#include <iostream>
using namespace std;

class X
{
    private:
        int var;
    protected:
        void fun () 
        {
            var = 10;
            cout << "\nFrom X" << var; 
        }
};

class Y : public X
{
    private:
        int var;
    public:
        void fun () 
        {
            var = 20;
            cout << "\nFrom Y" << var;
        }

        void call ()
        {
            fun ();

            X objX;
            objX.fun ();
        }
};

This results in:

这导致:

anisha@linux-dopx:~/> g++ type.cpp
type.cpp: In member function ‘void Y::call()':
type.cpp:9:8: error: ‘void X::fun()' is protected
type.cpp:32:14: error: within this context

I saw this: Accessing protected members in a derived class

我看到了这一点:访问派生类中的受保护成员

Given:

鉴于:

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.

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

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

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

更改构造函数以采用 Derived 实例也将解决问题。

How can this be accomplished without changing the constructor declaration?

如何在不更改构造函数声明的情况下完成此操作?

回答by 0lukasz0

I think that the thing you are trying to do should looks like this:

我认为您尝试做的事情应该是这样的:

#include <iostream>
using namespace std;

class X
{
    private:
        int var;
protected:
    virtual void fun () 
    {
        var = 10;
        cout << "\nFrom X" << var; 
    }
};

class Y : public X
{
private:
    int var;
public:
    virtual void fun () 
    {
        var = 20;
        cout << "\nFrom Y" << var;
    }

    void call ()
    {
        fun ();


        X::fun ();
    }
};

That way you can invoke hiden member from your base class. Otherwise you have to add friend X as it was pointed in other post.

这样你就可以从你的基类中调用隐藏的成员。否则你必须添加朋友 X,因为它在其他帖子中被指出。

回答by Anycorn

One solution is to add friend class Yto X.

一种解决方案是添加friend class Y到 X。

回答by jupp0r

See this example:

看这个例子:

#include <iostream>
using namespace std;

class X {
  private:
    int var;
  protected:
    void fun () 
    {
      var = 10;
      cout << "\nFrom X" << var; 
    }
};

class Y : public X {
  private:
    int var;
  public:
    void fun () 
    {
      var = 20;
      cout << "\nFrom Y" << var;
    }

    void call ()
    {
      fun(); /* call to Y::fun() */
      X::fun (); /* call to X::fun() */

      X objX;
      /* this will not compile, because fun is protected in X        
      objX.fun (); */

    }
};

int main(int argc, char ** argv)  {
  Y y;
  y.call();
  return 0;  
}

This yields

这产生

From Y20
From X10

Because you have overloaded the fun()-method in Y, you have to give the compiler a hint which one you mean if you want to call the fun-method in X by calling X::fun().

因为您fun()在 Y 中重载了-method,所以如果您想fun通过调用X::fun().

回答by justin

Well, if friendis ok, then this angle may as well be ok:

好吧,如果friend可以,那么这个角度也可以:

#include <iostream>

class X {
private:
    int var;
protected:
    virtual void fun() {
        var = 10;
        std::cout << "\nFrom X" << var;
    }

    static void Fun(X& x) {
        x.fun();
    }
};

class Y : public X {
private:
    int var;
public:
    virtual void fun() {
        var = 20;
        std::cout << "\nFrom Y" << var;
    }

    void call() {
        fun();
        X objX;
        objX.fun(); /* << ne-ne */
        Fun(objX); /* << ok */
    }
};

Of course, be mindful of the type you pass to X::Funif you use this as-is.

当然,X::Fun如果按原样使用它,请注意传递给的类型。

回答by Mr.Anubis

In void Y::call ()

在 void Y::call()

    X objX;
    objX.fun (); 

// here you're trying to access the protected member of objX , this/current object of Ydoesn't contains objXas it's base object , they both are different objects. That is why you can't access its member.

// 在这里,您尝试访问 objX 的受保护成员,this/ current object of Ydoes not contains objXas it's base object ,它们都是不同的对象。这就是您无法访问其成员的原因。

you can make Yfriend of Xas a solution told by @anycom.

你可以交Y朋友X作为@anycom 告诉的解决方案。

Edit: what I mean is, from inside Y(which is inherited from X) , you can simply call protected/public members of "it's"base class Xi.e you're accessing it's base members simply. But That doesn't means you can now access the protected members of all objects of type X, since you're trying to access those members from outer scope of class Xi.e via object of X. You know all these rules but it seem you did too much thinking 0_o

编辑:我的意思是,从内部Y(继承自X),您可以简单地调用“它的”基类的受保护/公共成员,X即您只是访问它的基成员。但这并不意味着您现在可以访问所有 type 对象的受保护成员X,因为您试图从类的外部范围(X即通过对象)访问这些成员X。你知道所有这些规则,但你似乎想太多了 0_o

回答by Mikhail

You are not accessing protected function in your derived class, you are trying to overload it and promote from protected to public. This is a forbidden action, you only can hide functions in derived class, e.g. overload protected function as a private.

您没有访问派生类中的受保护函数,而是试图重载它并将其从受保护提升为公共。这是一个被禁止的行为,您只能隐藏派生类中的函数,例如将受保护的函数重载为私有函数。

Accessing protected function means call it from some member of a class:

访问受保护的函数意味着从类的某个成员调用它:

class Y : public X
{
public:
    void call() {
      fun();
    }
}

or like you call it by objX.fun();is also correct.

或者像你这样称呼它objX.fun();也是正确的。