Sunday, April 7, 2013

Qt: T qobject_cast ( QObject * object ); How does it works ?

I think, you already know about the Qt Objects, and if not then please first refer Qt otherwise this document is not for you.

Now as you know that, the qobject_cast() function behaves similarly to the standard C++ dynamic_cast(), with the advantages that it doesn't require RTTI support and it works across dynamic library boundaries.

qobject_cast is defined as:-

template <class T>
inline T qobject_cast(QObject *object)
{
#if !defined(QT_NO_QOBJECT_CHECK)
    reinterpret_cast<T>(object)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(object));
#endif
    return static_cast<T>(reinterpret_cast<T>(object)->staticMetaObject.cast(object));
}

and furthermore the qt_check_for_QOBJECT_macro is defined as:-
 

template <typename T> inline void qt_check_for_QOBJECT_macro(const T &_q_argument) const
    { int i = qYouForgotTheQ_OBJECT_Macro(this, &_q_argument); i = i; }


template <typename T>
inline int qYouForgotTheQ_OBJECT_Macro(T, T) { return 0; }
template <typename T1, typename T2>
inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {} 
 
Now the above inline method qt_check_for_QOBJECT_macro() call is for checking that the object
that we are casting really contains the Q_OBJECT macro or not. 

This is a compile time check that ensures that any class cast with qobject_cast actually contains a Q_OBJECT macro. 
 
Note: qobject_cast will fail if a QObject subclass doesn't contain Q_OBJECT. In qt_check_for_QOBJECT_macro, 
we call a dummy templated function with two parameters, the first being "this" and the other the target of the 
qobject cast. If the types are not identical, we know that a Q_OBJECT macro is missing. You will get a compiler
error here, make sure that the class you are casting to contains a Q_OBJECT macro.
 
So if you have an object obj1 of type T and an object obj2 of type U, the call obj1->qt_check_for_QOBJECT_macro(obj2) 
calls the function qYouForgotTheQ_OBJECT_Macro() with parameters of types obj1* and obj2*. Because the function is 
templated with a single type parameter, the types T and U must be the same.
 
Now, if you call obj1->qt_check_for_QOBJECT_macro(obj1) then you should expect the types to be the same and 
for the compilation to trivially succeed. However, remember that this has the same type as the class the method was 
defined in. So if obj1 is of a class that was derived from T but doesn't contain its own definition of  
qt_check_for_QOBJECT_macro(), the call will fail.

No comments:

Post a Comment