2013-03-12 7 views
2

J'ai un problème avec l'héritage multiple.Héritage multiple en C++ (exemple Qt)

Je souhaite qu'un classe IEdge implémente QGraphicsItem "interface", qui contient des méthodes abstraites boundindRect() et paint (...). IEdge ajoute également de nouvelles méthodes.

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

Maintenant, je veux créer UndirectedEdge, qui s'étendent iEDGE, mais je ne veux pas mettre en œuvre boundingRect() et de la peinture (...) par moi-même, je veux utiliser la mise en œuvre IQGraphicsLineItem.

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

} 

Mais cela ne fonctionne pas, le compilateur dit que UndirectedEdge est abstraite parce que boundingRect() et de la peinture (...) ne sont pas mis en œuvre (mais je suis sûr que, IGraphicsLineItem contient ces méthodes). Je n'ai aucune idée, pourquoi ça ne marche pas. Merci beaucoup pour les explications.

Edit:

je peux résoudre ce problème, mais je suis seulement curieux. Dans ma langue principale C# cela fonctionnerait, il me manque quelque chose d'important sur l'héritage en C++ :-(... un indice serait apprécié, merci

Répondre

2

Je suppose que vous voulez dire que vous êtes héritant de QGraphicsLineItem, non IGraphicsLineItem. (Veuillez corriger si je me trompe.) QGraphicsLineItem hérite de QGraphicsItem.

Parce que vous êtes pas en utilisant héritage virtuel, vos objets UndirectedEdge contiennent effectivement deux cas de QGraphicsItem:

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

Un seul d'entre eux a ses fonctions abstraites correctement surchargées (l'QGraphicsLineItem un) . Le compilateur doit se plaindre de l'autre.

S'il vous plaît laissez-moi savoir si vous souhaitez que je développe sur cette explication - Je sais que c'est assez court!

0

Vous devez utiliser delegation pour construire votre UndirectedEdge avec une instance IQGraphicsLineItem de déléguer les appels appropriés à

1

Le compilateur est correct:..

iEDGE :: boundingRect() est pas mis en œuvre, IGraphicsLineItem :: boundingRect() est
iEDGE :: peinture() ne sont pas mis en œuvre, IGraphicsLineItem :: paint() est

Comme dit Ron, vous pouvez déléguer ces tâches comme ceci: 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 
} 
+0

Merci pour la solution, mais je suis juste curieux, pourquoi cela ne fonctionne pas. Je suis sûr que cela fonctionnerait en C# parfaitement :) Il me manque quelque chose sur l'héritage en C++ :-( – bidacek

+0

Le compilateur connaît la différence entre IEdge :: boundingRect() et IGraphicsLineItem :: boundingRect() ... ils ne sont pas la même fonction, même si une partie de la signature est épelée de la même manière. – Bill