leemes
leemes

Reputation: 45705

Downcast using C-style cast when knowing the concrete sub class type

In my project I have a tree of QObjects with different types. Let me give you a simple example which should give you the idea of what I'm talking about. This could be an exemplary QObject tree (not an inheritance diagram but somewhat similar to a class diagram), where we start with the root object at the top and listing its child objects below:

                                   City
                                     |
                                  Street
                                 /      \
                            House       ...
                           /     \
                       Floor     ...
                       /   \
                   Room    ...

While a QObject tree does not necessarily follow this rule, in my case very class in the tree has a parent of one particular type. So, to stay at one relation as an example, a house can have some floors and children of other types, but a floor is a child of a house and only a house.

Now if I model these as QObject derived classes, the interface of class Floor should give me its House *house() by internally looking what the QObject::parent() is. I really know that this parent will be of type House*, because I designed it to be so and the programmer(s) stick to this design.

Is it ok if I C-style cast the QObject *parent() to House* to implement House *house() const?

Qt suggests to use qobject_cast<House*>(parent()), returning 0 if the QObject* parent() doesn't inherit from House, making the cast type-safe. But in release mode, I want to avoid such slow casts. I profiled one particular algorithm which is performing three times faster when doing C-style casts instead of qobject_casts. This is because qobject_cast asks the meta object about the type-info during runtime, resulting in considerable slowdowns when called very often.

So what I ended up with was:

House *Floor::house() const {
    Q_ASSERT(qobject_cast<House*>(parent()));
    return (House*)parent();
}

This will assert in debug mode that the parent really is a House, while just C-style-casting efficiently in release mode.

To come to the point: I know people will yell when C++ programmers do C-style casts, but will it be ok in this situation?

An alternative solution would be to store the parent pointers of the particular types additionally as member variables, but I think this is redundant and I also like that the tree is reflected in those methods returning the tree parents.

Upvotes: 1

Views: 542

Answers (1)

Pete Becker
Pete Becker

Reputation: 76438

If you're sure that the ownership graph won't change, even during maintenance, then a cast that isn't type-checked is safe. You can use static_cast<House*>(parent()), which is fast, or, if you really want to, a C-style cast is okay. But the C-style cast is not faster than the C++ static_cast.

Upvotes: 3

Related Questions