2010-06-10 31 views
3

Comme la plupart des fonctions pratiques de QGraphicsScene et QGraphicsItem (telles que items(), collidingItems(), childItems() etc.) renvoient une QList, vous êtes obligé de faire beaucoup de qgraphicsitem_cast ou static_cast et QGraphicsItem :: Type() vérifient si vous avez des éléments différents dans la scène. Je pensais faire beaucoup de moulages de sous-classe n'étaient pas un style de codage souhaitable, mais je suppose que dans ce cas, il n'y a pas d'autre moyen viable, ou est-il?Beaucoup de blocs de pointeurs dans l'infrastructure et les performances de QGraphicsView

QList<QGraphicsItem *> itemsHit = someItem->collidingItems(Qt::IntersectsItemShape); 
foreach (QGraphicsItem *item, itemsHit) { 
    if (item->type() == QGraphicsEllipseItem::type()) { 
     QGraphicsEllipseItem *ellipse = qgraphicsitem_cast<QGraphicsEllipseItem *>(item); 
     // do something 
    } 
    else if (item->type() == MyItemSubclass::type()) { 
     MyItemSubClass *myItem = qgraphicsitem_cast<MyItemSubClass *>(item); 
     // do something 
    } 
    // etc 
} 

Le précédent qgraphicsitem_cast pourrait être remplacé par static_cast puisque le type correct est déjà vérifié. Lorsque vous en faites beaucoup tout le temps (scène très dynamique), les nombreux lancers influeront-ils sur les performances au-delà de l'évaluation habituelle d'if-else?

+1

+1 car j'ai le même problème. Une chose à noter est que vous pouvez stocker des données arbitraires (QVariant) contre chaque QGraphicsItem avec les méthodes setData()/data(), en accédant aux données par une clé. Cela pourrait être utile. – Rob

Répondre

0

Le surcoût de performance est principalement prépayé; c'est le résultat de l'overhead d'avoir le. type() membre. Il peut être efficace de récupérer le item->type() une fois. Vous savez que cela ne change pas, mais il y a des chances que le compilateur ne le fasse pas.

[edit] En outre, si vous avez vraiment beaucoup de types, il pourrait être utile d'introduire certains types intermédiaires. par exemple. if (dynamic_cast<MyGraphicsInterMediateType*>(item)) {/* check those types */} else {/* other types */}

+0

Ah, vous voulez dire le chercher une fois au début du bloc foreach? C'est un bon point. – kleimola

+0

Yup. Maintenant, vous allez le chercher pour chaque comparaison. Je pense que c'est un appel virtuel, et bien que pas cher, ceux-ci ne sont pas gratuits. Multipliez cela par chaque objet dans chaque scène, et vous avez beaucoup d'appels bon marché - alors plus bon marché, alors. – MSalters