0

I'm trying to derive a class from a Base that has a friend function defined. I want to create a friend function for my derived class that makes use of the Base's friend function, but preserves the type of my Derived class:

#include<algorithm>

class Base
{
public:
  Base(int i, int j, int k)
    {
      vect[0] = i;
      vect[1] = j;
      vect[2] = k;
    }
  ~Base();

  friend Base myMin (const Base& argA,
                     const Base& argB);
protected:
  // Member data
  int vect[3];
};

class Derived : public Base
{
public:
  Derived(int i, int j, int k)
    :
    Base(i,j,k)
    {
    }

  ~Derived();

  friend Derived doSomething(const Derived& argA,
                             const Derived& argB);
};

Base
myMin (const Base& argA,
       const Base& argB)
{
  int i = std::min(argA.vect[0], argB.vect[0]);
  int j = std::min(argA.vect[1], argB.vect[1]);
  int k = std::min(argA.vect[2], argB.vect[2]);
  return Base(i,j,k);
}

Derived doSomething(const Derived& argA,
                    const Derived& argB)
{
  // Does other stuff too...
  return myMin(argA, argB);
}

int main(int argc, char *argv[])
{
  Derived testA(2,4,6);
  Derived testB(3,3,7);

  doSomething(testA,testB);

  return 0;
}

I understand why this doesn't work (doSomething is given a Base to return, but is told to return Derived), and that this probably isn't very good C++ form. My Base class has a ton of friend functions similar to this, is there a way to make use of the friend functions with my Derived class without having to modify them?

Thank you

Edited: The error, for reference, is:

base.H: In function ‘Derived doSomething(const Derived&, const Derived&)’:
base.H:50:26: error: could not convert ‘myMin(const Base&, const Base&)((* &(& argB)->Derived::<anonymous>))’ from ‘Base’ to ‘Derived’
   return myMin(argA, argB);
Joshua
  • 3
  • 3
  • What purpose do friend functions have here? – Andrey Nasonov Oct 01 '15 at 23:00
  • Well in the example friend function access protected class member. But this design is ... let's say sub-optimal. Why not make those function, virtual member functions and use inheritance as it was meant to be used. – RedOctober Oct 01 '15 at 23:03
  • In the actual code, the friend functions are used to return a new instance of Base in cases where you don't want the arguments modified (e.g. Base baseC = myMin(baseA,baseB);). Also I can't modify the existing Base class because compatibility with existing code. I can add new members! I agree that it is suboptimal, unfortunately Base is something like 20 years old and doesn't have the best design decisions. – Joshua Oct 01 '15 at 23:05

1 Answers1

0

The most obvious way would be to change doSomething() to

 Derived doSomething(const Derived& argA,
                     const Derived& argB)
 {
      Base temp(myMin(argA, argB));
      Derived retval(temp.vect[0], temp.vect[1], temp.vect[2]);
      return retval;
 }

You'll probably also have to declare doSomething() to be a friend of Base as well.

Without knowing more about what you are REALLY trying to do, hard to advise further. The fact you need to do this at all is an example of a "code smell" - a positive sign that your design is flawed and, as your code keeps growing, you will keep needing to do workarounds like this. That gradually makes it harder and harder to change the code - each time you change one part, something else has to be worked around.

Peter
  • 35,646
  • 4
  • 32
  • 74
  • This is really ugly, I think I will try to find another way around so I don't use the friend functions (and I'll avoid creating new ones in my Derived class). Thank you for your response! – Joshua Oct 02 '15 at 00:11
  • That's my point. Ugly work-arounds are a sign of a broader problem in your design and/or code. – Peter Oct 02 '15 at 00:23