Sign in to follow this  
haphazardlynamed

C++ multiple inheritance name conflicts

Recommended Posts

Suppose I have two interfaces, Physical and Renderable, both of which have a method called 'update()'. And now I create a GameObject class which will implement both of those interfaces. When I define a new update() method in GameObject, how do I specify which of those two interfaces the definition is implementing? Not sure how this kind of conflict gets worked out. Thanks

Share this post


Link to post
Share on other sites
dave    2187
I think the problem really is, why is Update() in both IRenderable and IPhysical.

Questions you need to ask yourself:

- Will all objects that derrive from IRenderable also need to derrive from IPhysical?

- The other way round?

I think you probably need to derrive one from the other. Another solution is to define another base class that both of these derrive from, then google the diamond inheritance problem and take it from there.

Share this post


Link to post
Share on other sites
Zao    985
Implementing both base functions in a single class seems impossible since there's no way to disambiguate which implementation you're defining.
However, if a base derives from the interface and implements the function, the correct function will be called through an interface reference or pointer.

My suggested solution is using intermediary bases like this:
#include <iostream>

struct IFoo {
virtual ~IFoo() {}
virtual void f() = 0;
};

struct IBar {
virtual ~IBar() {}
virtual void f() = 0;
};

struct Qux;

struct QuxFoo : IFoo {
QuxFoo(Qux& qux) : qux(qux) {}
virtual void f();
private:
Qux& qux;
};

struct QuxBar : IBar {
QuxBar(Qux& qux) : qux(qux) {}
virtual void f();
private:
Qux& qux;
};

struct Qux : QuxFoo, QuxBar {
Qux() : QuxFoo(*this), QuxBar(*this) {}
void Say(std::string const& s) {
std::cout << s << std::endl;
}
};

void QuxFoo::f() { qux.Say("foo"); }
void QuxBar::f() { qux.Say("bar"); }

int main() {
Qux qux;
IFoo& ifoo = qux;
IBar& ibar = qux;

ifoo.f();
ibar.f();
}

Share this post


Link to post
Share on other sites
SiCrane    11839
You might want to use renaming in intermediate classes rather than implementation in intermediate classes. Ex:

struct PhysicalAdapter : Physical {
virtual void update(void) { physical_update(); }
virtual void physical_update(void) = 0;
};

struct RenderableAdapter : Renderable {
virtual void update(void) { renderable_update(); }
virtual void renderable_update(void) = 0;
};

struct GameObject : PhysicalAdapter, RenderableAdapter {
virtual void physical_update(void) { /* do stuff */ }
virtual void renderable_update(void) { /* do stuff */ }
};

Share this post


Link to post
Share on other sites
Antheus    2409
I don't use multiple inheritance much, but shouldn't this be used:

GameObject * ptr;

ptr->Renderable::Update();
ptr->Physical::Update();


At least that's appears to be formal syntax.

Share this post


Link to post
Share on other sites
Rydinare    487
Quote:
Original post by SiCrane
You might want to use renaming in intermediate classes rather than implementation in intermediate classes. Ex:

struct PhysicalAdapter : Physical {
virtual void update(void) { physical_update(); }
virtual void physical_update(void) = 0;
};

struct RenderableAdapter : Renderable {
virtual void update(void) { renderable_update(); }
virtual void renderable_update(void) = 0;
};

struct GameObject : PhysicalAdapter, RenderableAdapter {
virtual void physical_update(void) { /* do stuff */ }
virtual void renderable_update(void) { /* do stuff */ }
};


QFT. That was going to be my suggestion, as well.

Share this post


Link to post
Share on other sites
Zao    985
Quote:
Original post by Antheus
I don't use multiple inheritance much, but shouldn't this be used:
GameObject * ptr;

ptr->Renderable::Update();
ptr->Physical::Update();
At least that's appears to be formal syntax.

That would do exactly the wrong thing, since it would call the implementation in the interface base, ignoring all virtual dispatch.

Share this post


Link to post
Share on other sites
Hacksaw2201    100
This should help out if I understand what you're asking.

If you want to "override" what's in Physical::Update() or Renderable::Update() with your own method then just put your method within gameObject::Update() and don't bother with the other two instances. Someone wrote those for a different purpose.



class Physical
{
void Update();
}

class Renderable
{
void Update();
}

#include "Physical.h"
#include "Renderable.h"

class GameObject
{
Physical phys;
Renderable rend;

void Update();
}

#include "GameObject.h"

int main()
{
GameObject gameOb;

gameOb.Update();

gameOb.phys.Update();
gameOb.rend.Update();
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this