0

I usually try to find answers here before I post anything, but I'm not even sure how to formulate my question.

So here's what I want to do... I want to define a Base Interface, and a Derived Interface. Then, I want to implement the Base Interface, with extra variables and methods. Finally, I want to implemented a Derived class, from the implemented Base Interface BUT ALSO from the Derived Interface. I don't know about you, but my head hurts.

If I do something like below, I get Ambiguous definitions under the DerivedFloat code since that code "sees" both the GetBaseValue method from the IBase, inherited through IDerivedFloat, as well as the GetBaseValue inherited from Base.

Surely, there must be a way to derive a class which uses the expanded features of the Base Implementation, as well as making sure it implements the required IDerivedFloat methods.

Now... This is a dummy example to show what I'm conceptually trying to achieve. It's not a real life example.

template <typename VALUE_TYPE>
class IBase
{
public:
  virtual VALUE_TYPE GetBaseValue() const = 0;
};

class IDerivedFloat : public IBase<FLOAT>
{
public:
  virtual void SetBaseValue(const FLOAT & value) = 0;
};

// Implementation of Base
template <typename VALUE_TYPE>
class Base : public IBase<VALUE_TYPE>
{
public:
  VALUE_TYPE GetBaseValue() const { return m_BaseValue; }

protected:
  VALUE_TYPE m_BaseValue;
}

// Uses expanded Base AND implements IDerivedFloat
class DerivedFloat : public Base<FLOAT>, public IDerivedFloat
{
public:
   void SetBaseValue(const FLOAT & value) { m_BaseValue = value };
}
ThermoX
  • 277
  • 3
  • 11
  • *I usually try to find answers here before I post anything* -- So you didn't find "diamond inheritance" or [virtual inheritance](http://stackoverflow.com/questions/21558/in-c-what-is-a-virtual-base-class) in any of your searches? – PaulMcKenzie Jun 21 '16 at 16:48
  • Not an expert in C++. First time I've heard of the term diamond inheritance. As far as "virtual inheritance", I have. But clearly, from your comment, I don't know how to that information to solve my problem. – ThermoX Jun 21 '16 at 16:50
  • Did you click the link in my comment? It basically is a duplicate of the answer you accepted. – PaulMcKenzie Jun 21 '16 at 17:03

2 Answers2

3

You can use virtual inheritance to work around this problem:

class IDerivedFloat : virtual IBase<FLOAT>
{
public:
  virtual void SetBaseValue(const FLOAT & value) = 0;
};

template <typename VALUE_TYPE>
class Base : virtual IBase<VALUE_TYPE>
{
public:
  VALUE_TYPE GetBaseValue() const { return m_BaseValue; }

protected:
  VALUE_TYPE m_BaseValue;
}

Using virtual inheritance gives the derive class one instance of the base class members, instead of one from each time it exists in the class hierarchy.

Andy
  • 30,088
  • 6
  • 78
  • 89
  • Thanks Andy! That looks like it does what I wanted to do... And your answer is a little more informative than "duh, haven't you looked into virtual inheritance" :) – ThermoX Jun 21 '16 at 16:56
0

Multiple inheritance is an issue precisely because of the ambiguity issue you ran into, but there are ways to get around it. You have to explicitly tell the compiler which super you are calling the ambiguous functions from, by leading the function call with the super's name and a double colon.

Example:
- C inherits from A and B.
- A and B both have add() function.
- In C, you have to say A::add() or B::add() to tell the compiler which one to use.

Link for details and more complete implementation: http://www.cprogramming.com/tutorial/multiple_inheritance.html

Kadima
  • 249
  • 5
  • 14
  • Thanks. I actually did try that! But what bugged me is that the derived class will be carrying both definitions... Which I was trying to avoid. This leads me to conclude that I may not be approaching the problem the right way, maybe?? – ThermoX Jun 21 '16 at 16:53
  • The only idea I would have if you're trying to stop having both functions would be maybe to override them with another function in the child itself, but that doesn't get rid of the parent's functions, just covers them. They'd still be accessible. I'm not sure you can inherit only parts of a class, you have to inherit it all-or-nothing. – Kadima Jun 21 '16 at 16:58
  • Andy above provided the answer. Thanks again for your help Kadima. – ThermoX Jun 21 '16 at 17:00