Доступ к унаследованным функциям - PullRequest
0 голосов
/ 13 октября 2018

При множественном наследовании, когда весь базовый класс содержит одно и то же имя функции с разной функциональностью, мы можем получить доступ к защищенной функции из определенного базового класса, используя оператор разрешения области действия «::».Однако я попробовал что-то еще.Я создал объекты базового класса внутри дочернего класса.И попытался вызвать функцию, используя сквозной объект этого конкретного класса.Но я получил следующую ошибку компилятора: «void A :: func (int &) 'защищен в этом контексте».Пожалуйста, дайте мне знать, где я ошибся.

 #include <iostream>
using namespace std;
class A
{
    protected:
        void func(int & a)
        {
            a = a * 2;
        }
};

class B
{
  protected:
        void func(int & a)
        {
            a = a * 3;
        }
};

class C
{
  protected:
        void func(int & a)
        {
            a = a * 5;
        }
};

 class D : public A,public B,public C {
     public: 
     int a;
     A a_val;
     B b_val;
     C c_val;
     void update_val(int new_val)
    {
     a = new_val;
     a_val.func(a);
     b_val.func(a);
     c_val.func(a);
     }
   void check(int); 
};

void D::check(int new_val)
{
    update_val(new_val);
    cout << "Value = " << a << endl;
};

int main()
{
    D d;
    int new_val;
    cin >> new_val;
    d.check(new_val);
}

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

Когда вы находитесь в вашем производном классе, у него есть доступ к его собственным методам предка.Но он не имеет доступа к вашим переменным, защищенным членами, а также к закрытым методам и переменным.

Перепроектируйте свой код, вы пытаетесь что-то сделать и искажаете дизайн других классов по плохим причинам.Код Фрэнсиса - хорошее решение, но D не нужно ни от чего наследовать.

0 голосов
/ 13 октября 2018

Если вы хотите, чтобы ваш код с базовыми классами имел независимую функциональность и при этом оставался защищенным, самый простой способ решить вашу проблему - слегка изменить имя защищенных функций и добавить открытую функцию, которая вызывает защищенные члены:Посмотрите эти объявления класса, например:

class A {
public:
    void func( int& a ) {
        func_impl( a );
    }
protected:
    void func_impl( int& a ) {
        a = a * 2;
    }
};

class B {
public:
    void func( int& b ) {
        func_impl( b );
    }
protected:
    void func_impl( int& b ) {
        b = b * 3;
    }
};

class C {
public:
    void func( int& c ) {
        func_impl( c );
    }
protected:
    void func_impl( int& c ) {
        c = c * 5;
    }
};

class D : public A, public B, public C {
public:
    int a;
    A a_val;
    B b_val;
    C c_val;

    void update_val( int val ) {
        a = val;
        a_val.func( a );
        b_val.func( a );
        c_val.func( a );
    }

    void check( int );
};

void D::check( int val ) {
    update_val( val );
    std::cout << "Value = " << a << std::endl;
}

Это обеспечивает хороший публичный интерфейс для вызова защищенных функций-членов.Это также решает проблему доступа к protected members.Когда я запускаю вашу программу и ввожу значение 5, она возвращает результат 150 и работает как положено.


Этот фрагмент должен показать вам, как работает наследование, когда вы можете и не можетеДоступ к защищенным членам:

class DerivedA : public Base {
public:
    Base b;

    void call_message() {
        b.message(); // Protected Member of Base class can not be accessed
    }
};

class DerivedB : public Base {
public:
    void call_message() {
        message(); // This works without problem!
    }
};

Точно так же, как я делал выше, один из способов решения этой проблемы - добавление вызывающей стороны открытого интерфейса к защищенной реализации.

class Base {
public:
    void message() {
        message_impl();
    }
protected:
    void message_impl() {
        std::cout << "This is a protected member of Base\n";
    }
};

Теперь вы можете сделать это:

class DerivedA {
public:
    Base b;

    void call_message() {
        b.message();      // Accessible through public interface.
    }
};
...