Reputation: 101
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
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
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
Reputation:
You should use delegation. Simply construct your UndirectedEdge with an IQGraphicsLineItem instance to delegate the appropriate calls to.
Upvotes: 0