Multiple inheritance and interface methods

user2366975

For several graphic objects I inherit from QGraphicsLineItem, QGraphicsRectItem and so on.

class CustomLine : public QGraphicsLineItem{};

class CustomRect : public QGraphicsRectItem{};

Those objects are added to a container, a custom subclass of a QGraphicsScene "scene" that is meant for displaying and interacting with those items. this->scene->items() returns a list of QGraphicItem's: QList<QGraphicsItem* >

What I want to do is each custom object class to have the same custom interface methods, for example setModeX(). Then I could do stuff like:

Foreach (BaseItem *item, this->scene->items()){
    item->setModeX(...);
}

But how do I achieve that? If I make an interface like

class BaseItem{
    public: setModeX(); [...]
    private: Mode mode_;
} 

and inherit

class CustomLine : public QGraphicsLineItem, BaseItem {};

So while the scene should only contain items based on BaseItem (not sure if this is really needed for this task), I first retrieve a list of objects of one of its 2 base classes, namely QGraphicsItem, and need to cast it to its other base class BaseItem to use the interface methods. I will probably not be able to cast a CustomLine-item to BaseItem in the loop above, because it does not know about the other base class.

EDIT:

  • I use MinGW 4.8 32 bit (g++).

  • I noticed that when I start the foreach-loop, the items in my scene disappear (yet don't see the reason why)

jxh

Since scene is a QGraphicsScene, it only consists of QGraphicsItems. So you cannot directly iterate over scene as BaseItems as you show in your code. You have to iterate over each QGraphicsItem. You describe that you could downcast to your CustomLine and then upcast back to a BaseItem, but this only works if you know that all the items in the scene are lines. If scene contains other types of items, your technique would require you to iterate of each kind of item until you found a downcast that worked, and then cast it back to BaseItem.

QGraphicsItem
          \         BaseItem
QGraphicsLineItem   /
            \      /
            CustomLine

A simple solution would have been available to you if the Qt library had used virtual inheritance on QGraphicsItem. Then, you would simply need to use virtual inheritance on QGraphicsItem from BaseItem, and then down casting would have worked.

           QGraphicsItem
            /        \
QGraphicsLineItem   BaseItem
            \        /
           CustomLineItem

Since Qt does not do so, you would either need to make custom changes to the Qt library, or code in your own conversion mechanism.

Assuming you are unwilling to make custom modifications to the Qt library itself, then one approach is to create a mapping between Qt's QGraphicsItem and your BaseItem. The mapping can be done within the constructor of your BaseItem, and undone from BaseItems destructor. To make undoing the mapping more efficient, you can also create a link from the BaseItem to the QGraphicsItem.

class BaseItem {
    static std::unordered_map<QGraphicsItem *, BaseItem *> map;
    QGraphicsItem *link_;
public:
    BaseItem (QGraphicsItem *q) : link_(q) {
        //...
        map[q] = this;
    }
    virtual ~BaseItem () {
       map.erase(link_);
       //...
    }
    static BaseItem * getBaseItem (QGraphicsItem *q) {
        std::unordered_map<QGraphicsItem *, BaseItem *>::iterator i;
        if ((i = map.find(q)) == map.end()) return NULL;
        return i->second;
    }
    //...
};

//...
std::unordered_map<QGraphicsItem *, BaseItem *> BaseItem::map;

In your derived classes, you would simply need to pass this to the BaseItem constructor.

class CustomLine : public QGraphicsLineItem, public BaseItem {
public:
    CustomLine () : BaseItem(this) {
        //...
    };
    //...
};

And then your loop would use the static BaseItem::getBaseItem() function to convert from a QGraphicsItem pointer to a BaseItem pointer. Thus, since there is no way to create a useable inheritance relationship between QGraphicsItem and BaseItem, their relationship is recorded in a table.

QGraphicsItem <-----------------. link
          \         BaseItem <--' map
QGraphicsLineItem   /
            \      /
            CustomLine

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Java

Using multiple onClick methods in a single interface for RecyclerView

From Java

Inheritance - Calling methods within methods

From Java

Do C# 8 default interface implementations allow for multiple inheritance

From Dev

Multiple Interface inheritance in C#

From Dev

Python and order of methods in multiple inheritance

From Dev

GNU Smalltalk - Inheritance and Multiple Parameter Methods/Constructors

From Dev

Multiple inheritance, inheriting an interface and an implementation

From Dev

Typescript name collision/clash using multiple interface inheritance

From Dev

virtual methods inheritance class

From Dev

Interface inheritance - Issue with double inheritance

From Dev

Dissassembling virtual methods in multiple inheritance. How is the vtable working?

From Dev

are multiple methods ok in an interface definition?

From Dev

Multiple inheritance with interface in C++

From Dev

Problems in multiple interface inheritance

From Dev

Multiple Inheritance Ambiguity with Interface

From Dev

Invoke multiple generic interface methods on a class through reflection

From Dev

Call an interface function from an unknown derived class (multiple inheritance)

From Dev

Jackson and multiple interface inheritance

From Dev

Calling different methods from different traits in scala with multiple inheritance

From Dev

Interface inheritance combined with class inheritance

From Dev

Runtime multiple inheritance with impromptu-interface

From Dev

SWIG JAVA how to wrap C++ multiple inheritance with %interface and pure virtual methods

From Dev

How to wrap child methods multiple times in an inheritance tree?

From Dev

Why not multiple abstract methods in Functional Interface in Java8?

From Dev

Call an interface function from an unknown derived class (multiple inheritance)

From Dev

Jackson and multiple interface inheritance

From Dev

Interface inheritance combined with class inheritance

From Dev

c# interface inheritance - not recognizing base interface methods

From Dev

Multiple templated interface inheritance name hiding

Related Related

  1. 1

    Using multiple onClick methods in a single interface for RecyclerView

  2. 2

    Inheritance - Calling methods within methods

  3. 3

    Do C# 8 default interface implementations allow for multiple inheritance

  4. 4

    Multiple Interface inheritance in C#

  5. 5

    Python and order of methods in multiple inheritance

  6. 6

    GNU Smalltalk - Inheritance and Multiple Parameter Methods/Constructors

  7. 7

    Multiple inheritance, inheriting an interface and an implementation

  8. 8

    Typescript name collision/clash using multiple interface inheritance

  9. 9

    virtual methods inheritance class

  10. 10

    Interface inheritance - Issue with double inheritance

  11. 11

    Dissassembling virtual methods in multiple inheritance. How is the vtable working?

  12. 12

    are multiple methods ok in an interface definition?

  13. 13

    Multiple inheritance with interface in C++

  14. 14

    Problems in multiple interface inheritance

  15. 15

    Multiple Inheritance Ambiguity with Interface

  16. 16

    Invoke multiple generic interface methods on a class through reflection

  17. 17

    Call an interface function from an unknown derived class (multiple inheritance)

  18. 18

    Jackson and multiple interface inheritance

  19. 19

    Calling different methods from different traits in scala with multiple inheritance

  20. 20

    Interface inheritance combined with class inheritance

  21. 21

    Runtime multiple inheritance with impromptu-interface

  22. 22

    SWIG JAVA how to wrap C++ multiple inheritance with %interface and pure virtual methods

  23. 23

    How to wrap child methods multiple times in an inheritance tree?

  24. 24

    Why not multiple abstract methods in Functional Interface in Java8?

  25. 25

    Call an interface function from an unknown derived class (multiple inheritance)

  26. 26

    Jackson and multiple interface inheritance

  27. 27

    Interface inheritance combined with class inheritance

  28. 28

    c# interface inheritance - not recognizing base interface methods

  29. 29

    Multiple templated interface inheritance name hiding

HotTag

Archive