Доступ к унаследованным функциям

При множественном наследовании, когда весь базовый класс содержит одно и то же имя функции с различной функциональностью, мы можем получить доступ к защищенной функции из определенного базового класса, используя оператор разрешения области действия «::».
Однако я попробовал что-то еще. Я создал объекты базового класса внутри дочернего класса. И попытался вызвать функцию, используя сквозной объект этого конкретного класса.
Но я получил следующую ошибку компилятора:
«Oid 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

Решение

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

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

1

Другие решения

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

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

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector