PDA

View Full Version : Problem with QGraphicsItem Casting



D Cell
9th April 2010, 05:33
I have a problem with type casting. I have developed a base class from QGraphicsItemGroup that will have an arbitrary number of children that are an instance of a subclass of the base class. I want to be able to perform base class functions on all of the children so I need a list of pointers to the children. The problem is that the children are of varying types (of subclass) and I cant seem to properly cast from QGraphicsItem* to Base* for instances of the subclasses. I think it is a problem with casting to a middle level of inheritance. I have provided a simplified example (which I have not actually compiled and tested, but should illustrate my problem):


#include <QGraphicsItem>
#include <QGraphicsItemGroup>

class Base : public QGraphicsItemGroup
{
public:
Base(){}
enum { Type = QVariant::UserType + 1000 };
int type() const { return Type; }
static bool isBasedOffChild(QGraphicsItem *item);
QList<Base *> childBaseItems();
void test(){}
};

class SubClass1 : public Base
{
public:
SubClass1(){}
enum { Type = Base::Type + 1 };
int type() const { return Type; }
};

class SubClass2 : public Base
{
public:
SubClass2(){}
enum { Type = Base::Type + 2 };
int type() const { return Type; }
};

bool Base::isBasedOffChild(QGraphicsItem *item)
{
if(item->type() > Base::Type)
return true;
else
return false;
}

QList<Base *> Base::childBaseItems()
{
QList<QGraphicsItem *> items = childItems();
QList<Base *> baseItems;
for(int i = 0; i < items.size(); i++)
{
if(isBasedOffChild(items.at(i)))
{
baseItems.append(qgraphicsitem_cast<Base *>(items.at(i)));
}
}
return baseItems;
}


If i execute the following code, I get memory access faults.


Base *parent = new Base();
parent->addToGroup(new SubClass1());

QList<Base *> items = parent->childBaseItems();

for(int i = 0; i < items.size(); i++)
{
//Causes memory faults
items.at(i)->test();
}


It would appear the problem is that I cannot do this:


QGraphicsItem * item = new SubClass1();
qgraphicsitem_cast<Base *>(item);


Is it possible to cast to a middle layer of the inheritance hierarchy like this? I don't want the subclasses to have to deal with the details of type casting and the parent class should not need to know anything about the child classes so therefore can't do any type casting from them. Does anybody have any suggestions? Thanks.

D Cell
9th April 2010, 19:11
I seem to have found the problem. Doing the following works:


QGraphicsItem * item = new SubClass1();
dynamic_cast<Base *>(item);


The qgraphicsitem_cast documnetation states:

Note: To make this function work correctly with custom items, reimplement the type() function for each custom QGraphicsItem subclass.

Since I am not casting to the exact type defied by qgraphicsitem::type(), but to my base class instead, it would appear that I need to use a dynamic cast.