Reputation: 45705
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
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