1

I am curious if there is a neat way to expose methods in the base class of a derived interface.

So in code: -

class cbase {
public:
  void MyMethodA() { }
};

class cderived : public cbase {
public:
  void MyMethodB() { }
}

class ibase { 
public:
  virtual void MyMethodA() = 0;
};
class iderived : public ibase {
public:
  virtual void MyMethodB() = 0;
};

Now if I make cbase inherit ibase, and cderived implement iderived, the compiler will complain that when I instantiate cderived, MyMethodA() is abstract and not implemented.

MyMethodA() is implemented in the base class and through ibase. Is the only way to fix this to reimplement ibase's methods in the cderived class? If so, yuck!

So as below: -

class cbase : public ibase {
public:
  void MyMethodA() { }
};

class cderived : public cbase, public iderived {
public:
  void MyMethodA() { cbase::MyMethodA(); }
  void MyMethodB() { }
};

cderived inst;
iderived *der = &inst;  
der->MyMethodA();
der->MyMethodB();
ibase *bas = der;
bas->MyMethodA();

I hope this is enough to convey the question. :) It might sound a little loopy as we are trying to refactor old code.

I am sure there is plenty of eager commentary out there ;)

David Thornley
  • 1,278
  • 1
  • 12
  • 15

2 Answers2

2

If I understand correctly you want to make ibase a virtual base class of iderived and cbase.

This was there is only one instance of each of your interface classes in the class hierarchy and when you join cbase and iderived together at the cderived level the non-virtual override of MyMethodA in cbase is used because it is the dominating override.

See here: Hidden Features of C++?

E.g.

class ibase { 
public:
  virtual void MyMethodA() = 0;
};
class iderived : public virtual ibase {
public:
  virtual void MyMethodB() = 0;
};

class cbase : public virtual ibase {
public:
  void MyMethodA() { }
};

class cderived : public cbase, public virtual iderived {
public:
  void MyMethodB() { }
};

int main()
{
    cderived inst;
    iderived *der = &inst;  
    der->MyMethodA();
    der->MyMethodB();
    ibase *bas = der;
    bas->MyMethodA();
}
Community
  • 1
  • 1
CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • iderived and cbase don't need to virtually inherit from their base classes, no? – BЈовић Mar 16 '11 at 07:51
  • @VJo: I don't understand your question, sorry. – CB Bailey Mar 16 '11 at 07:53
  • Wow, so I just ignore the dominance warning in visual-c and it's all honky-dory? I'm impressed :) – David Thornley Mar 16 '11 at 07:58
  • in other words : why this : `class iderived : public virtual ibase` ? Why not just `class iderived : public ibase`? – BЈовић Mar 16 '11 at 08:37
  • @VJo: `ibase` is, effectively, and interface class. If it wasn't a virtual base class at both points in the class hierarchy then there would be two copies of the base class and the `MyMethodA` would need to be overridden in both branches of the inheritance tree. If `ibase` wasn't a virtual base class of `iderived` then the `cbase` implementation of `MyMethodA` wouldn't be an override for the `ibase` copy that was the non-virtual base class of `iderived`. – CB Bailey Mar 16 '11 at 08:46
  • @VJo: The other way around. `ibase` needs to be a virtual base of both `iderived` and `cbase`, strictly `iderived` doesn't need to be a virtual base of `cderived` but it's more consistent with the pattern and would support more derived interface classes without changes to the rest of the hierarchy. – CB Bailey Mar 16 '11 at 09:05
0

Take a look into multiple inheritance.

The answer to that faq item is basically answer to your question :

class cderived : public virtual cbase {
public:
  void MyMethodB() { }
}

class ibase { 
public:
  virtual void MyMethodA() = 0;
};
class iderived : public virtual ibase {
public:
  virtual void MyMethodB() = 0;
};
BЈовић
  • 62,405
  • 41
  • 173
  • 273
  • I think that the point of the question was to find a way to avoid having to implement the "pass-through" version of `MyMethodA`. – CB Bailey Mar 16 '11 at 07:58