Bug 386134 - Add qgraphicsitem_cast check.
Summary: Add qgraphicsitem_cast check.
Status: CONFIRMED
Alias: None
Product: clazy
Classification: Developer tools
Component: general (show other bugs)
Version: unspecified
Platform: Other All
: NOR wishlist
Target Milestone: ---
Assignee: Sergio Martins
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-10-24 08:32 UTC by Roman
Modified: 2017-10-24 09:54 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Roman 2017-10-24 08:32:47 UTC
Hi, i want to propose new check. Recently i worked with QGraphicsItem and wanted to cast a pointer. Because i use Qt i prefer to use it's cast functions, for example qobject_cast. But somehow qgraphicsitem_cast did not work as i expected it should be for "_cast" function. My first guess was to reimplement the type() function as mentioned in documentation. But this did not help me too. Then after some time i figured out that qgraphicsitem_cast can only cast from QGraphicsItem pointer to real object type, you can't get nothing on "middle" of hierarchy with it. And i was trying to get item's parent. My mistake.

To sum up thoughts i propose check if the type() reimplemented for item used with qgraphicsitem_cast. Without it it will not work. And also check if developer doesn't try to cast on "middle". This will also doesn't work.

Yes, this is stupid mistake i did, but for someone such a check can potentially save several hours. Hope you will like my idea.
Comment 1 Sergio Martins 2017-10-24 09:15:45 UTC
QGraphicsItem *item = ...;
if you do qgraphicsitem_cast<Foo>(item);

I can warn if Foo::type() is missing, indeed.

But what's this about "middle" ?
If Foo derives from Bar, and Bar::type() is also implemented, isn't this OK ?

Sorry, I've never used qgraphicsitem_cast
Comment 2 Roman 2017-10-24 09:30:21 UTC
See, this cast function is very tricky. Let's imagine such an hierarchy:

class Bar : public QGraphicsItem
{
    virtual int type() const Q_DECL_OVERRIDE {return Type;}
    enum { Type = UserType + 1};
};

class Foo : public Bar
{
    virtual int type() const Q_DECL_OVERRIDE {return Type;}
    enum { Type = UserType + 2};
};

Foo *f = new Foo();

Bar *b = f;

b->type() == f->type();

Because the type() function is virtual in both cases you will get the same result from Foo::type(). This looks obvious. But what if i want use qgraphicsitem_cast like this:

QGraphicsItem *p = new Foo();
Bar *parent = qgraphicsitem_cast<Bar *>(p);

It will not work! qgraphicsitem_cast can only cast to Foo in this case. If i want to cast to Bar i must not to reimplement the type() function in Foo.