6

I have a question about multiple inheritance of protected function and polymorphism. It's quite hard to describe it so I hope it will be clear enough.

Say I have three classes:

class baseClass
{
 protected:
    virtual int function() = 0;
}; 


class derived_A:public baseClass
{
  int function()
    {
      //implementation 1
    };
};


class derived_B:public baseClass
{
   int function()
     {
       //implementation 2
     };
 };


class derived_C:public derived_A, public derived_B
{
  baseClass ** p_arr; //array of pointers of baseClass kind (polymorphism)
  int x=0;

  for (int i=0; i<arraySize; i++) // array size = many classes like derived_A, derived_B...
  {
     x = p_arr[i]->function(); //I already have function that builds this array
                               //it is not the question so I didn't put it here.
     // process x
   }

};

Finally my question is - how can I access that "protected" function() from derived_C class (inside the for loop)? I am a bit confused... and will be happy for explanation.

Thanks.

Guy Avraham
  • 3,482
  • 3
  • 38
  • 50
user1673206
  • 1,671
  • 1
  • 23
  • 43

2 Answers2

2

When C++ permits access to protected members, it's only to the members of this object (as mentioned here and here). The code x = p_arr[i]->function() tries to call a method in another object, so the compiler complains.

To fix your code, you can make function public, or add a friend declaration to baseClass, like this:

class baseClass
{
 public:
    virtual int function() = 0;
}; 

Or

class baseClass
{
 protected:
    friend class derived_C;
    virtual int function() = 0;
}; 

However, to retain the protected access and not mention the name of the derived class in the base class, you can fix your code by adding a static accessor function to the base class:

class baseClass
{
 protected:
    virtual int function() = 0;
    static int call_the_function_on_object(baseClass& obj) {return obj.function();}
}; 

Use it (in a derived class) this way:

x = call_the_function_on_object(*p_arr[i]);

You can also give the accessor function the same name, but then, if your derived_C overrides the virtual method, it will hide the accessor function. You can fix that by referring to the base class explicitly:

class baseClass
{
 protected:
    virtual int function() = 0;
    static int function(baseClass& obj) {return obj.function();}
}; 

...
class derived_C:public derived_A, public derived_B
{
    ...
        x = baseClass::function(*p_arr[i]);
    ...
}
Community
  • 1
  • 1
anatolyg
  • 26,506
  • 9
  • 60
  • 134
  • thank you for your detailed answer! I tried to begin with your first solution of declaring the function as friend: at the BaseClass: friend int derived_c::function(); but I get this error: 'derived_C' : is not a class or namespace name why do I get this message? – user1673206 Jan 05 '15 at 08:51
  • also, if I add #include BaseClass, it will be circular include and "bad design" as I saw on other posts... or maybe I wrong? – user1673206 Jan 05 '15 at 08:56
  • As far as I know, it's impossible to declare a friend method in an undeclared class. So just make the whole `derived_C` class a friend. I have added the syntax to do it. – anatolyg Jan 05 '15 at 09:22
  • I made the derived_C a friend of BaseClass. thank you! – user1673206 Jan 05 '15 at 13:01
1

In this case your function() is private in derived classes. So, from derived_C you cannot directly access that function.

However, if you are willing to make it public/protected. Then you can use:-

derived_C dc;
dc.derived_A::function();
dc.derived_B::function();
ravi
  • 10,994
  • 1
  • 18
  • 36