PDA

View Full Version : help dynamic_cast



giorgik
2nd October 2012, 19:18
I have a problem to make the
dynamic_cast<Ostacolo *>(ostacolo) see the following code snippet:


QList<QGraphicsItem *> collisioniOstacolo = scene()->collidingItems(this);
QList<QGraphicsItem *>::Iterator iter;
for(iter = collisioniOstacolo.begin(); iter != collisioniOstacolo.end(); ++iter)
{
QGraphicsItem *ostacolo = *iter;
if((*iter)->collidesWithItem(this))
{
Ostacolo *pOstacolo = dynamic_cast<Ostacolo *>(ostacolo);
qDebug() << "Toccato un " << pOstacolo->objectName();
}
}

I get this error when compiling:


C:\Qt\4.8.3\src\corelib\global\qglobal.h:2505: error: 'dynamic_cast_will_always_fail_because_rtti_is_dis abled' is not a member of 'Ostacolo*'

What did I do wrong?

wysota
2nd October 2012, 20:46
You have RTTI disabled :) Even if you didn't, your code would instantly crash (unless all items in the list are Ostacolo instances but then you wouldn't need dynamic_cast at all).

Use qgraphicsitem_cast instead.

Besides, this code doesn't have any sense -- first you're getting a list of items colliding with "this" and then you're checking again if each item in the list collides with "this" -- since you got that item from the list of items colliding with "this", the condition will always be true.

giorgik
3rd October 2012, 10:42
thanks wysota, you're right, the code does not make much sense. Unfortunately I have the ideas a little confused.
What I want to do is from the list of items that collide with this (ie Robot) to verify which of these items is an Ostacolo and obtain its coordinates. Could you help me to write this piece of code ?

wysota
3rd October 2012, 11:05
class X : public Scene {
public:
// ...
Ostacolo* addObstacle(....) {
Ostacolo *ost = new Ostacolo(...);
// ...
listOfObstacles << ost;
return ost;
}
protected:
QList<QGraphicsItem*> collidingObstacles() const {
QList<QGraphicsItem*> colls = robotItem->collidingItems();
QList<QGraphicsItem*> obstacles;
foreach(QGraphicsItem *item, colls) { if(listOfObstacles.contains(item)) obstacles << item; }
return obstacles;
}

private:
QList<QGraphicsItem*> listOfObstacles;
Robot *robotItem;
};

giorgik
3rd October 2012, 11:36
Can you explain me the code, I did not understand ?

wysota
3rd October 2012, 12:09
Which part you don't understand?

giorgik
3rd October 2012, 16:51
I tried your code but I do not detect collisions against Robot Obstacle. The class Robot call his method collisioniRobot(), see code:


void Robot::timerEvent(QTimerEvent *event)
{
event->timerId();

// individua eventuali collisioni del robot contro ostacolo
collisioniRobot();
}

void Robot::collisioniRobot()
{
// individuazione base collisioni
if(scene()->collidingItems(this).isEmpty())
{
// not collision
}
else
{
// collision
}
...

in the code (else) I would call your function collidingObstacles that returns a list QList<QGraphicsItem*> I would call collisions. In fact here is not put nothing.
I'm
class Robot : public QGraphicsSvgItem e
class Ostacolo : public QGraphicsSvgItem

wysota
3rd October 2012, 17:20
I don't see how your code is related to what I have written before. First of all my code should be put in the scene, not in the item, because it is the scene that knows all the items. If you want to pass pointers to every possible object in the scene to the robot object so that you can compare if the robot has bumped into any of them, then that's probably not a very good design.

giorgik
3rd October 2012, 17:40
OK, then I have to review my project and transfer control of the item on the scene. In my project I have several instances of Robot and Ostacolo and for each of them (Robot) checks for a collision that may occur against an obstacle (Ostacolo) or against another Robot. How do you advise me is this possible ?

wysota
3rd October 2012, 17:48
In my opinion you should do that in the scene and only if an interesting collision occurs, pass this information to the interested object. Otherwise if robots A and B collided, you would check this condition twice -- once in A and once in B but since by checking it in A you already know that B collided with A, there is no point in checking it again. The code is much cleaner and much faster.

giorgik
3rd October 2012, 19:19
waiting for your answer, I rewrote the code according to your advice. It presents a new problem due to the istance of the Robot (I create 2 Robot and 1 Ostacolo). Wanting to implement "in the scene and only if an interesting collision occurs, pass this information to the interested object" how should I do ?
I'm sorry if I'm so boring, but for me it is important to be able to solve the problem.

wysota
3rd October 2012, 19:52
Wanting to implement "in the scene and only if an interesting collision occurs, pass this information to the interested object" how should I do ?
I'm sorry if I'm so boring, but for me it is important to be able to solve the problem.

Take a piece of paper and develop an algorithm of how it should work. Then take a look at API offered by the Graphics View Framework and implement your algorithm with it. If you need some functionality that is missing in the API, come here and ask about it and we'll help you find a solution. Remember that to use Qt you need a decent knowledge of C++. If you lack that knowledge, it's better to learn it now than to struggle at every step.

giorgik
5th October 2012, 08:29
I managed to solve the problem by following your advice and structuring the program better. thanks