1

This code doesn't work.

class Collidable{
   public:
   virtual Vec2 Pos()=0;
};

class Square{
    Vec2 pos;
    public:
    Vec2 Pos(){
        return pos;
    }
};
class Box:public Square,public virtual Collidable{

};
main(){
    Box bla;
   cout<<bla.Pos()<<endl;
}

but if I do this it works.

class Box:public Square,public virtual Collidable{
   public:
    Vec2 Pos(){
        return Square::Pos();
    }
}

My problem is I have a class like Square and I have lots of functions like Pos(), and I really feel like I shouldn't have to state something like this

    Vec2 Pos(){
        return Square::Pos();
    }

for every single function over and over again when this is what I would have thought would be the default behavior when inheriting from another class. How can I avoid a lot of redudant typing here, and what's so ambiguous about calling Pos(), when there's only one definition for it?

Tiby312
  • 53
  • 5

1 Answers1

3

The ambiguous part is caused by the fact that you have 2 functions in your class heirarchy that have the same function name, but are different (that is, Square::Pos and Collidable::Pos have no relation to each other). You must state which function you are using in your Box class. Without knowing the rest of your architecture, it is difficult to recommend a solution, but I would guess that you don't really need multiple inheritance here. You can probably change it to this:

class Collidable
{
public:
   virtual Vec2 Pos()=0;
};

class Square : public Collidable
{
    Vec2 pos;
public:
    virtual Vec2 Pos()
    {
        return pos;
    }
};

class Box : public Square
{

};

main()
{
    Box bla;
    cout<<bla.Pos()<<endl;
}
Zac Howland
  • 15,777
  • 1
  • 26
  • 42
  • Sorry, I should have explained that my point in introducing a Collidable interface was to make Box collidable while making Square NOT collidable. In your example, the square would also be collidable making it the same thing. – Tiby312 Nov 13 '13 at 20:08
  • You can do that with a simple boolean flag. There is no need to introduce a class heirarchy to support that. In general, when you see yourself using multiple inheritance for more than a collection of abstract base classes (e.g. interface classes), chances are you can solve the same problem in a more simple solution. The problem in your code, as I explained, is that you have 2 different virtual methods with the same name coming from different base classes. You must specify which one you want to override, or rename one of them. – Zac Howland Nov 13 '13 at 20:14
  • While the questions are different, the answers [here](http://stackoverflow.com/a/5368930/529761) and [here](http://stackoverflow.com/a/6845874/529761) are relevant to what you are trying to do. – Zac Howland Nov 13 '13 at 20:18
  • But I'm not using multiple inheritance for more than a collection of abstract base classes. Box inherits from only one parent, and implements one interface. There is only one defined function and only one pure virtual function. Yes I could use a boolean flag, but when you have many different such interfaces, or different types, I think that would be a lot of extra runtime checks when I'd prefer to be able to know at compile time. Plus it can make sense for whether something is collidable or not to be part of its type. – Tiby312 Nov 13 '13 at 20:33
  • That gets into the philosophical portion of it a bit too much. Suffice it to say, you cannot do what you want to do without explicitly saying which function you want to use (via a `using` directive or a fully-scoped call). – Zac Howland Nov 13 '13 at 22:04