Как получить доступ к защищенным членам в производном классе? - PullRequest
3 голосов
/ 04 февраля 2012

С 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

Я видел это: Доступ к защищенным членам в производном классе

Дано:

Вы можете получить доступ к защищенным членам только в случаях вашеготип (или производный от вашего типа).Вы не можете получить доступ к защищенным членам экземпляра родительского или двоюродного типа.

В вашем случае класс Derived может получить доступ только к члену b экземпляра Derived, но не к другому экземпляру Base.

Изменение конструктора на экземпляр Derived также решит проблему.

Как это можно сделать без изменения объявления конструктора?

Ответы [ 6 ]

6 голосов
/ 04 февраля 2012

Я думаю, что то, что вы пытаетесь сделать, должно выглядеть так:

#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, как было указано в другом сообщении.

6 голосов
/ 04 февраля 2012

Одним из решений является добавление friend class Y к X.

2 голосов
/ 04 февраля 2012

См. Этот пример:

#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

Поскольку вы перегрузили fun() -метод в Y, вы должны дать компилятору подсказку, какую вы имеете в виду, если хотите вызвать fun -метод в X, вызвав X::fun().

1 голос
/ 04 февраля 2012

Ну, если 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 голос
/ 04 февраля 2012

В недействительном Y :: call ()

    X objX;
    objX.fun (); 

// здесь вы пытаетесь получить доступ к защищенному члену objX, this / текущий объект Y не содержит objX в качестве базового объекта, они оба являются разными объектами. Вот почему вы не можете получить доступ к его участнику.

вы можете сделать Y другом X как решение, предложенное @ anycom.

Редактировать: я имею в виду, что из Y (который унаследован от X) вы можете просто вызывать защищенных / открытых членов "it" base class X т.е. Доступ к базам просто. Но это не означает, что теперь вы можете получить доступ к защищенным членам всех объектов типа X, поскольку вы пытаетесь получить доступ к этим членам из внешней области видимости класса X, т. Е. Через объект X. Вы знаете все эти правила, но, кажется, вы слишком много думали 0_o

0 голосов
/ 04 февраля 2012

Вы не получаете доступ к защищенной функции в своем производном классе, вы пытаетесь ее перегрузить и продвигать из защищенной в общедоступную. Это запрещенное действие, вы можете скрыть только функции в производном классе, например, Функция защиты от перегрузки как частная.

Доступ к защищенной функции означает вызов ее у какого-либо члена класса:

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

или как вы называете это objX.fun(); также правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...