bidacek
bidacek

Reputation: 101

Multiple inheritance in c++ (Qt example)

I have a problem with multiple inheritance.

I want a class IEdge to implement QGraphicsItem "interface", which contains boundindRect() and paint(...) abstract methods. IEdge also add some new methods.

class IEdge : public QGraphicsItem
{
public:
virtual Vertex * getVertex1() = 0;
virtual Vertex * getVertex2() = 0;
}

Now I want to create UndirectedEdge, which extend IEdge, but i don't want to implement boundingRect() and paint(...) by myself, i want to use IQGraphicsLineItem implementation.

class UndirectedEdge : public IEdge, public IGraphicsLineItem
{
public:
virtual Vertex* getVertex1();
virtual Vertex* getVertex2();

}

But that doesn't work, compiler says that UndirectedEdge is abstract because boundingRect() and paint(...) aren't implemented (but I'm sure that, IGraphicsLineItem contains these methods). I've no idea, why it doesn't work. Thank you very much for explanation.

Edit:

I can solve this, but I'm only curious. In my primary language C# it would work, I'm missing something important about inheritance in C++ :-( ... some hint would be appreciated, thanks.

Upvotes: 2

Views: 2066

Answers (3)

Dan Nissenbaum
Dan Nissenbaum

Reputation: 13928

I assume you mean that you're inheriting from QGraphicsLineItem, not IGraphicsLineItem. (Please correct if I'm wrong.) QGraphicsLineItem inherits from QGraphicsItem.

Because you are not using virtual inheritance, your UndirectedEdge objects actually contain two instances of QGraphicsItem:

UndirectedEdge::IEdge::QGraphicsItem // 1st instance of QGraphicsItem - abstract functions not defined!!
UndirectedEdge::QGraphicsLineItem::QGraphicsItem // 2nd instance - abstract items are defined just fine

Only one of these has its abstract functions properly overridden (the QGraphicsLineItem one). The compiler must be complaining about the other one.

Please let me know if you'd like me to elaborate on this explanation - I know it is quite short!

Upvotes: 2

Bill
Bill

Reputation: 14695

The compiler is correct:

IEdge::boundingRect() is not implemented, IGraphicsLineItem::boundingRect() is.
IEdge::paint() is not implemented, IGraphicsLineItem::paint() is.

As Ron said, you can delegate these tasks like so: http://ideone.com/mfdr0p

#include <iostream>

class Base1
{
public:
  virtual void func1() = 0;
};

class Base2
{
public:
  virtual void func1();
};

void Base2::func1()   // This is the function you want to use
{
  std::cout << "Base2::func1()" << std::endl;
}

class Derived : public Base1
{
public:
  virtual void func1();   // Override as normal
private:
  Base2 m_base2;
};

void Derived::func1()
{
  m_base2.func1();   // Delegation happens here
}

Upvotes: 1

user1898811
user1898811

Reputation:

You should use delegation. Simply construct your UndirectedEdge with an IQGraphicsLineItem instance to delegate the appropriate calls to.

Upvotes: 0

Related Questions