首页 文章

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

提问于
浏览
3

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

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

那么,在派生类中访问受保护函数 fun 的方法是什么?

#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 ();
        }
};

这导致:

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

我看到了这个:Accessing protected members in a derived class

鉴于:

您只能访问类型实例中的受保护成员(或从您的类型派生) . 您无法访问父级或堂兄类型的实例的受保护成员 . 在您的情况下,Derived类只能访问Derived实例的b成员,而不能访问其他Base实例 . 更改构造函数以获取Derived实例也将解决该问题 .

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

6 回答

  • 2

    我认为你要做的事情应该是这样的:

    #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 ();
        }
    };
    

    这样您就可以从基类中调用hiden成员 . 否则你必须添加朋友X,因为它在其他帖子中指向 .

  • 1

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

  • 6

    看这个例子:

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

    这产生了

    From Y20
    From X10
    

    因为您在Y中重载了 fun() -method,所以如果要通过调用 X::fun() 来调用X中的 fun -method,则必须给编译器一个提示 .

  • -1

    好吧,如果 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 */
        }
    };
    

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

  • 1

    在void Y :: call()中

    X objX;
        objX.fun ();
    

    //这里你试图访问objX的受保护成员, this / Y 的当前对象不包含 objX ,因为它's base object , they both are different objects. That is why you can' t访问其成员 .

    作为@anycom告诉的解决方案,你可以 X 的朋友 X .

    编辑:我的意思是,从 Y (继承自 X )内部,您可以简单地调用 "it's" 基类 X 的受保护/公共成员,即您're accessing it'的基本成员 . 但这并不意味着你现在可以访问 X 类型的所有对象的受保护成员,因为你试图从类 X 的外部范围访问那些成员,即通过 X 的对象 . 你知道所有这些规则,但似乎你做了太多的思考0_o

  • 6

    您没有在派生类中访问受保护的函数,您正试图使其超载并从受保护升级到公共 . 这是一个禁止的动作,你只能隐藏派生类中的函数,例如过载保护功能作为私人 .

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

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

    或者像 objX.fun(); 所说的那样也是正确的 .

相关问题