3

In multiple inheritance,where all the base class contains same function name with different functionality, we can access the protected function from particular base class using "::" scope resolution operator. However, I tried something else. I created the objects of the base class in inside the child class. And tried calling the function using through object of that particular class. But I was getting the following compiler error: "‘void A::func(int&)’ is protected within this context." Please let me know where did i go wrong.

 #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);
}
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Prasad Barude
  • 31
  • 1
  • 3
  • 5
    Possible duplicate of [Accessing protected members in a derived class](https://stackoverflow.com/questions/3247671/accessing-protected-members-in-a-derived-class) – user202729 Oct 13 '18 at 07:16
  • 1
    Actually this is a method, https://stackoverflow.com/questions/4672438/how-to-access-protected-method-in-base-class-from-derived-class may be more suitable. – user202729 Oct 13 '18 at 07:22
  • 2
    What are you inheriting from A, B and C if you don't need them. It usually does not make much sense to derive from a class and have a member of the same type. If you use an object that is not of the same type as the class itself, you need either public access or friendship. Then why make `func` protected if you want public access to it? – Phil1970 Oct 13 '18 at 14:19
  • Are A, B and C classes your own code or some external librairies that you prefer not to modify so that you won't have to modify the library each time it is updated or if the library is compiled by the vendor (no source), you might want to avoid the risk of undefined behavior if the change is not compatible. – Phil1970 Oct 13 '18 at 14:31
  • 2
    The design seems to be dead wrong. If you inherit from A, B and C and then have member variables from A, B and C just to have access to their protected methods, go back to the board and redesign your code. It's bad. Very bad. – Matthieu Brucher Oct 13 '18 at 18:43
  • "_However, I tried something else."_ Why? This question is incomplete without a rationale for why you're trying to do what you think you want to do. Without that, offering advice on how to keep using a confusing and, most likely, highly questionable design is irresponsible. @user202729 A member function is still a member (and saying "methods" about C++ is just going to lead to long and boring arguments about other languages), so the 1st one is OK too. – underscore_d Oct 13 '18 at 18:57
  • A lot of people are pointing out the code is convoluted. The reason for this is that this is a [HackerRank challenge](https://www.hackerrank.com/challenges/accessing-inherited-functions). – Giskard Apr 27 '22 at 15:14

3 Answers3

1

If you want to keep your code with the base classes as having independent functionality and still remaining protected the easiest way to resolve your issue is by slightly changing the name of your protected functions and adding a public function that calls the protected members: See these class declarations for example:

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

This provides a nice public interface to call the protected member functions. This also resolves the issue of accessing the protected members. When I run your program and input a value of 5 it returns a result of 150 and works as expected.


This snippet should show you how inheritance works and when you can and can not access protected members:

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

Just as I did above one way to resolve this is by adding a public interface caller to the protected implementation.

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

Now you can do this:

class DerivedA {
public:
    Base b;

    void call_message() {
        b.message();      // Accessible through public interface.
    }
};
Francis Cugler
  • 7,788
  • 2
  • 28
  • 59
1

When you are in your derived class, it has access to its own ancestor methods. But it doesn't have access to your variables member protected and private methods and variables.

Redesign your code, you are trying things and contorting the other classes design for bad reasons. Francis' code is a good solution, but D doesn't need to inherit from anything.

Matthieu Brucher
  • 21,634
  • 7
  • 38
  • 62
0

If you don't want to create another function, you can do something like this:

#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;
     void update_val(int new_val)
    {
     a = new_val;
     this->A::func(a);
     this->B::func(a);
     this->C::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);
}

This works because, this refers to the current instance of class D, and it already inherits class A, class B, class C. So you can directly access the protected functions of the respective classes.

Remember: It will not work if you have not inherited the classes.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Harsh patel
  • 445
  • 5
  • 11