I'm reading ``C++ GUI Programming with Qt 4", where I found the following statement
Unlike the Standard C++ dynamic_cast(), Qt’s qobject_cast() works correctly across dynamic library boundaries.
A similar statement appears in the official Qt documentation at
https://doc.qt.io/qt-5/qobject.html#qobject_cast
What does it mean? Where exactly we cannot use dynamic_cast in C++ ? And what about virtual functions? Is it safe to use them with dynamically linked libraries?
dynamic_cast −This cast is used for handling polymorphism. You only need to use it when you're casting to a derived class. This is exclusively to be used in inheritence when you cast from base class to derived class.
While typeid + static_cast is faster than dynamic_cast , not having to switch on the runtime type of the object is faster than any of them.
In C++, dynamic casting is mainly used for safe downcasting at run time. To work on dynamic_cast there must be one virtual function in the base class. A dynamic_cast works only polymorphic base class because it uses this information to decide safe downcasting.
Yes, dynamic_cast is a code smell, but so is adding functions that try to make it look like you have a good polymorphic interface but are actually equal to a dynamic_cast i.e. stuff like can_put_on_board .
In concept, dynamic_cast
can work across module boundaries. But, some compilers/linkers cut corners in the name of performance. One of the ways to improve performance when loading shared libraries is to make as few symbols visible to other libraries as possible. This reduces the amount of work the loader has to do because it doesn't have to resolve as many symbols. RTTI symbols are on the chopping block and are among those not exposed to other modules by default. GCC's documentation describes this and the workaround here.
Unfortunately, this makes things a mess when it comes to RTTI. The module that constructed an object and the one performing the dynamic_cast
might hold their own, otherwise identical, RTTI symbols for a type. This makes them appear as different types when the dynamic_cast
is performed in a different module, causing dynamic_cast
to unexpectedly return nullptr
, or throw std::bad_cast
for references.
Special care is required when linking and when calling dlopen()
for the loader to know to resolve RTTI symbols between modules on module load.
Also, historically Qt has supported platforms which either do not support RTTI, or where RTTI would have too much of an overhead. So, qobject_cast
was invented to remove the reliance on RTTI altogether while still providing a way to cast between polymorphic types.
To answer your other questions:
dynamic_cast
anywhere RTTI is available but dynamic linking can make this difficult.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With